Compare commits
923 Commits
1
...
3637022890
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3637022890 | ||
![]() |
5f3a78e7ce | ||
![]() |
c7872ad841 | ||
![]() |
9eeab756e4 | ||
![]() |
ef971a1236 | ||
![]() |
5ec851a120 | ||
![]() |
2a94ff2ef6 | ||
![]() |
1738892500 | ||
![]() |
765d876a51 | ||
![]() |
a0c8e26b38 | ||
![]() |
4b4f4b3d8f | ||
![]() |
63fe7a88eb | ||
![]() |
871ee1a6b6 | ||
![]() |
6a36599a29 | ||
![]() |
d11ab20617 | ||
![]() |
ea713edfb5 | ||
![]() |
ff48a9dea2 | ||
![]() |
0a1812ec8c | ||
![]() |
113d4ac078 | ||
![]() |
4d49385529 | ||
![]() |
94a8455267 | ||
![]() |
406d2a054c | ||
![]() |
932296afb6 | ||
![]() |
27fb36a6c5 | ||
![]() |
f5e0f21869 | ||
![]() |
180c35d5c2 | ||
![]() |
4bd25f3220 | ||
![]() |
1299f107dd | ||
![]() |
43ae40e077 | ||
![]() |
1af0b00892 | ||
![]() |
36f7219964 | ||
![]() |
529ad853ee | ||
![]() |
4e37ccfff8 | ||
![]() |
134c68c705 | ||
![]() |
ea61e87b31 | ||
![]() |
6e82008ffa | ||
![]() |
016bcc00d8 | ||
![]() |
936e7508e3 | ||
![]() |
34220ab759 | ||
![]() |
51ba63faae | ||
![]() |
f4f1e397cb | ||
![]() |
721117ce1b | ||
![]() |
2da917add7 | ||
![]() |
678c53dc39 | ||
![]() |
d57359b2ff | ||
![]() |
3796d9f8b4 | ||
b6d84e0e66 | |||
![]() |
3dbdbefc58 | ||
![]() |
23570c7270 | ||
![]() |
4d5024f8b8 | ||
![]() |
ea8670702a | ||
![]() |
b8828f48c9 | ||
![]() |
b468fef242 | ||
![]() |
358f8eeca3 | ||
![]() |
150a70e69f | ||
![]() |
b9fb0f2bcd | ||
![]() |
d4a8b8e400 | ||
![]() |
8009c9a5f9 | ||
![]() |
177115e2fc | ||
![]() |
85bc12df59 | ||
![]() |
1da818b0d5 | ||
![]() |
c23d3f1442 | ||
![]() |
6500ce9154 | ||
![]() |
63ecaff1bc | ||
![]() |
e29c268d0b | ||
![]() |
2758e89a51 | ||
![]() |
d0670d0244 | ||
![]() |
1e2005451c | ||
![]() |
29a95ca592 | ||
![]() |
5bfff2a398 | ||
![]() |
4d26947208 | ||
![]() |
f1de741bd5 | ||
![]() |
3394d93b43 | ||
![]() |
02c64feff8 | ||
![]() |
f2ba162359 | ||
![]() |
16c5d11ead | ||
![]() |
3e97c5d5fc | ||
![]() |
cb5499f82f | ||
![]() |
3d71c1bcbe | ||
![]() |
a12793e67a | ||
![]() |
affec9bb61 | ||
![]() |
fb62ec4c77 | ||
![]() |
c48cf1a2f7 | ||
![]() |
cf5cc92258 | ||
![]() |
ca934fe514 | ||
![]() |
d6ca75006a | ||
![]() |
51a9878363 | ||
![]() |
7664c44697 | ||
![]() |
5a8ee72622 | ||
![]() |
492b2de520 | ||
![]() |
900d3212a4 | ||
![]() |
d8997e1239 | ||
![]() |
e1001534e4 | ||
![]() |
59a69ed486 | ||
![]() |
437574328e | ||
![]() |
87af7ada40 | ||
![]() |
aa01730c13 | ||
![]() |
0803b401e7 | ||
![]() |
6d974d799b | ||
![]() |
1fa779b21f | ||
![]() |
2c5442c044 | ||
![]() |
db4324c478 | ||
![]() |
a8afca4ccf | ||
![]() |
6849bab741 | ||
![]() |
ff72f24433 | ||
![]() |
19ea1b204c | ||
![]() |
a9e8dc7b9f | ||
![]() |
ee14eac009 | ||
![]() |
3c1bbd5a7f | ||
![]() |
218cfaca44 | ||
![]() |
8a78d76a20 | ||
![]() |
1ead9f1443 | ||
![]() |
c53dd48437 | ||
![]() |
001a1d648c | ||
![]() |
6bbd162c72 | ||
![]() |
8fb8476994 | ||
![]() |
8d7a2faf1b | ||
![]() |
df946f8525 | ||
![]() |
58f8c315e6 | ||
![]() |
c6a379048e | ||
![]() |
02dd52ccb9 | ||
![]() |
abb93af3fb | ||
![]() |
06b18b8fb9 | ||
![]() |
88772a0d8e | ||
![]() |
89c2bf0932 | ||
![]() |
9a0e6336b7 | ||
![]() |
550a754fab | ||
![]() |
5921f7f889 | ||
![]() |
e097880e95 | ||
![]() |
99a0dc6c53 | ||
![]() |
ef7e4a752d | ||
![]() |
cded8e54fb | ||
![]() |
f17a903555 | ||
![]() |
191aba1f95 | ||
![]() |
e8d7a7f8bf | ||
![]() |
836c1084c4 | ||
![]() |
649bfdc220 | ||
![]() |
8d6529ccf1 | ||
![]() |
c936692403 | ||
![]() |
c3d3f2ab50 | ||
![]() |
f289b19310 | ||
![]() |
9866231129 | ||
![]() |
e0b5b54dda | ||
![]() |
2687ecc02e | ||
![]() |
3699920515 | ||
![]() |
4481da75b7 | ||
![]() |
037b636be9 | ||
![]() |
12ded24cd4 | ||
![]() |
2b5c13e3da | ||
![]() |
043f07190c | ||
![]() |
dc0758274e | ||
![]() |
0d9aa85a6a | ||
![]() |
810440abe7 | ||
![]() |
177aaebaf8 | ||
![]() |
ba11c565d8 | ||
![]() |
5320d3a4fd | ||
![]() |
82f181b80b | ||
![]() |
eb43fa7c4c | ||
![]() |
86c0357725 | ||
![]() |
844dac6106 | ||
![]() |
0a923e98ab | ||
![]() |
a85a5bd055 | ||
![]() |
ca51798445 | ||
![]() |
73146ea643 | ||
![]() |
f186f4aa5c | ||
![]() |
a4d89af418 | ||
![]() |
4eb755fed6 | ||
![]() |
95837605b8 | ||
![]() |
3f4bf3f6fd | ||
![]() |
adb71068e3 | ||
![]() |
68f898dbf8 | ||
![]() |
296b714282 | ||
![]() |
d88f38cf2a | ||
![]() |
a8098c2c4c | ||
![]() |
1eb91889d4 | ||
![]() |
ac451d0fcd | ||
![]() |
5d7e0a1260 | ||
![]() |
8344207608 | ||
![]() |
cc45168e25 | ||
![]() |
81c898dd9e | ||
![]() |
87aa50c7be | ||
![]() |
a080047632 | ||
![]() |
bb4b3dfe61 | ||
![]() |
55aaa6e2c6 | ||
![]() |
1fc866eeee | ||
![]() |
15e0692b41 | ||
![]() |
6db42dc736 | ||
![]() |
c1d86a4238 | ||
![]() |
ec761dbe3d | ||
![]() |
1328a314de | ||
![]() |
06b0a1292f | ||
![]() |
11a16a54fc | ||
![]() |
548cbb4bda | ||
637ae21089 | |||
![]() |
6febc4d2fc | ||
![]() |
8253db1486 | ||
![]() |
8fe1b0891b | ||
![]() |
ff1d7f7f1c | ||
![]() |
c437a18288 | ||
![]() |
0992c39132 | ||
![]() |
610f978c44 | ||
![]() |
84ea9266c2 | ||
![]() |
54abaebe17 | ||
![]() |
a16c860ba8 | ||
![]() |
b1b7e3439f | ||
![]() |
1df75fe25c | ||
![]() |
4d0e0b8ef8 | ||
![]() |
36002def70 | ||
![]() |
8247ac54a1 | ||
![]() |
f4fe80b28a | ||
![]() |
9e052d6e3a | ||
![]() |
0da18b81b6 | ||
![]() |
fc81c6329b | ||
![]() |
3d92b989ce | ||
![]() |
b942e8a950 | ||
![]() |
29131b4644 | ||
![]() |
b897b118ca | ||
![]() |
145af2b6ee | ||
![]() |
09a38a854c | ||
![]() |
995779a294 | ||
![]() |
67f38fc646 | ||
![]() |
316f1fa925 | ||
![]() |
21f5ad6c0a | ||
![]() |
6e6e52f316 | ||
![]() |
71c19b3ef2 | ||
![]() |
0befc6385d | ||
![]() |
22371b4b07 | ||
![]() |
913d711b80 | ||
![]() |
d17d12c805 | ||
![]() |
4d64109e2c | ||
![]() |
d66d807cff | ||
![]() |
e7a68f06b3 | ||
![]() |
fd49e86e17 | ||
![]() |
337621ca4a | ||
![]() |
0e38a4e4f0 | ||
![]() |
c19a160c9c | ||
![]() |
c390e06e63 | ||
![]() |
00d6a948d0 | ||
![]() |
6f1c2a1a81 | ||
![]() |
47ba907eb7 | ||
![]() |
a14252493f | ||
![]() |
328c4288c2 | ||
![]() |
b7c11ff852 | ||
![]() |
add1d6225d | ||
![]() |
182424ba05 | ||
![]() |
bf86cd2a51 | ||
![]() |
2085e9cafd | ||
![]() |
fb51236ae2 | ||
![]() |
9509b5825c | ||
![]() |
b8a8acdad7 | ||
![]() |
898e5f8bda | ||
![]() |
30a39497aa | ||
![]() |
852a220076 | ||
![]() |
a34d56b7df | ||
![]() |
13feaa7581 | ||
![]() |
14df9ea705 | ||
![]() |
6bd2bb884a | ||
![]() |
89cdaa611a | ||
![]() |
cc476a26b4 | ||
![]() |
14d132638d | ||
![]() |
9e62636059 | ||
![]() |
a3b2b4920a | ||
![]() |
e7f128ee59 | ||
![]() |
e1069c265e | ||
![]() |
e0b356c12d | ||
![]() |
769d900383 | ||
![]() |
8d99100601 | ||
![]() |
0c1c8080a6 | ||
![]() |
1742541b03 | ||
![]() |
d66e6967ee | ||
![]() |
559879301d | ||
![]() |
c524c92062 | ||
![]() |
b329329333 | ||
![]() |
5df8ef98a1 | ||
![]() |
55154b2996 | ||
![]() |
89aa6aecff | ||
![]() |
970456e6b0 | ||
![]() |
97effae8dc | ||
![]() |
f26755045d | ||
![]() |
067af8356c | ||
![]() |
ee743674c2 | ||
![]() |
362f8a3c99 | ||
![]() |
9f0ecd7f73 | ||
![]() |
d01f582646 | ||
![]() |
cdc8f159f5 | ||
![]() |
b481b6e1b5 | ||
![]() |
505aeff544 | ||
![]() |
dbf0444110 | ||
![]() |
07d753f413 | ||
![]() |
f516e89a5f | ||
![]() |
5f15bca561 | ||
![]() |
d98acd8c39 | ||
![]() |
97502a5bd5 | ||
![]() |
806184aa5d | ||
![]() |
d93fb1fdfc | ||
![]() |
9cf922ae80 | ||
![]() |
2070efc35a | ||
![]() |
1dc4dbf7af | ||
![]() |
c10634f1e3 | ||
![]() |
c0f8fd8c6b | ||
![]() |
95f89792d4 | ||
![]() |
a299abf18f | ||
![]() |
0cc15390a4 | ||
![]() |
379b23b42d | ||
![]() |
160b1b240a | ||
![]() |
5af69377e5 | ||
![]() |
bcee0a5964 | ||
![]() |
804128c3d3 | ||
![]() |
4e3ee024ac | ||
![]() |
c300fdbfb1 | ||
![]() |
840ff11335 | ||
![]() |
8d76b51683 | ||
![]() |
a78bb51831 | ||
![]() |
db19d0819e | ||
![]() |
72b76221f7 | ||
![]() |
9eb32034b7 | ||
![]() |
24f88b5ffe | ||
![]() |
d27ebad011 | ||
![]() |
1cebd8551b | ||
![]() |
446d5aeb15 | ||
![]() |
58f8ce605d | ||
![]() |
3fae2fdae5 | ||
![]() |
c268407ce3 | ||
![]() |
cd435c5f41 | ||
![]() |
74b0e3bded | ||
![]() |
edc0a14ef1 | ||
![]() |
011be78b27 | ||
![]() |
58008e6758 | ||
![]() |
ae21727c12 | ||
![]() |
a480372d3d | ||
![]() |
0bc298014d | ||
![]() |
63f85a8099 | ||
![]() |
cc16d5ba15 | ||
![]() |
fa3afe188e | ||
![]() |
6df2db86c3 | ||
![]() |
7791de490d | ||
![]() |
754a8c7250 | ||
![]() |
88b0f31590 | ||
![]() |
b17dbb37e4 | ||
![]() |
4ec360219a | ||
![]() |
b4d4da7250 | ||
![]() |
8bf809a888 | ||
![]() |
90e0cee86c | ||
![]() |
5b571362e3 | ||
![]() |
9537003a6d | ||
![]() |
bdc50283d2 | ||
![]() |
85c8968d75 | ||
![]() |
1466ad9bef | ||
![]() |
0cda2241ed | ||
![]() |
3ac96d9ed4 | ||
![]() |
9f7b6a281b | ||
![]() |
96bd5f8259 | ||
![]() |
62917c2a50 | ||
![]() |
10ea780cdc | ||
![]() |
19561bb1f1 | ||
![]() |
8088789f51 | ||
![]() |
5dec91caa3 | ||
![]() |
0c28a9a79b | ||
![]() |
8c2b715f93 | ||
![]() |
0fe75031a9 | ||
![]() |
0ec01f8d6f | ||
![]() |
fbcb3f8cbc | ||
![]() |
3f6a454052 | ||
![]() |
088fda12f8 | ||
![]() |
b207b30108 | ||
![]() |
f12b67088f | ||
![]() |
2643daf0b2 | ||
![]() |
21188dad73 | ||
![]() |
0476854d7c | ||
![]() |
b9ab4f6484 | ||
![]() |
759d92db4d | ||
![]() |
263fea1c52 | ||
![]() |
949e9216ff | ||
![]() |
547835f59d | ||
![]() |
464ed17741 | ||
![]() |
1ca8b06d74 | ||
![]() |
5312549db1 | ||
![]() |
21a8a0467f | ||
![]() |
c5dfd43e48 | ||
![]() |
879bc9bd98 | ||
![]() |
5a484c3952 | ||
![]() |
a1dd917227 | ||
![]() |
6186fa7e1b | ||
![]() |
2c227955c7 | ||
![]() |
1ac50714f5 | ||
![]() |
fd1d6a98f1 | ||
![]() |
43b5e7e644 | ||
![]() |
13ab68e5b1 | ||
![]() |
165caab526 | ||
![]() |
187e5a752a | ||
![]() |
dc81568c45 | ||
![]() |
9fe9d92e04 | ||
![]() |
1e550ac0a3 | ||
![]() |
1190209409 | ||
![]() |
c7cc6b54bf | ||
![]() |
c1afce2939 | ||
![]() |
aa40c04302 | ||
![]() |
bddf07efee | ||
![]() |
c8a45cb085 | ||
![]() |
f6720b3d37 | ||
![]() |
dc8f5e9b25 | ||
![]() |
8a2d3e1aed | ||
![]() |
afeaf4444b | ||
![]() |
f69a284b3f | ||
![]() |
9f1bb44824 | ||
![]() |
037a29551c | ||
![]() |
b4ea970c29 | ||
![]() |
719b80baa1 | ||
![]() |
f6002f05e0 | ||
![]() |
0867654347 | ||
![]() |
687a6d8693 | ||
![]() |
6fc362cae2 | ||
![]() |
5d03bae931 | ||
![]() |
408e51535d | ||
![]() |
d4749f4eb8 | ||
![]() |
829501c1b1 | ||
![]() |
88ef5a3467 | ||
![]() |
e52948efcc | ||
![]() |
56466f889b | ||
![]() |
5ecfab65fa | ||
![]() |
98fc65ec43 | ||
![]() |
3e37e2cdc4 | ||
![]() |
2efb08197f | ||
![]() |
dd7cb72a25 | ||
![]() |
b73fc88313 | ||
![]() |
465db2cd22 | ||
![]() |
73c1dc8118 | ||
![]() |
509a202f93 | ||
![]() |
09a9884b9f | ||
![]() |
6afc5aa98e | ||
![]() |
9e497fb5e8 | ||
![]() |
16476256c3 | ||
![]() |
623430359a | ||
![]() |
6ab53802df | ||
![]() |
d5f877b83d | ||
![]() |
0b33702712 | ||
![]() |
10fce45248 | ||
![]() |
b39e5ba1d5 | ||
![]() |
700df030f0 | ||
![]() |
a44fe15fea | ||
![]() |
12d1553f5a | ||
![]() |
503c2580d7 | ||
![]() |
8ab9509ceb | ||
![]() |
197eded6d0 | ||
![]() |
1813ad400a | ||
![]() |
a1b048a2f9 | ||
![]() |
cb43ad3488 | ||
![]() |
e8daf67276 | ||
![]() |
00ef191ad0 | ||
![]() |
e8d559f6d0 | ||
![]() |
82ed892166 | ||
![]() |
45bd4a72a4 | ||
![]() |
7196d83833 | ||
![]() |
2b7c311a2b | ||
![]() |
7ef4e45945 | ||
![]() |
db08ea1587 | ||
![]() |
af3227684b | ||
![]() |
46788cc6c6 | ||
![]() |
70a45f3dc8 | ||
![]() |
d63e3dadbc | ||
![]() |
93109f1e19 | ||
![]() |
c4e74ee8a5 | ||
![]() |
534fbe1a6b | ||
![]() |
e9f0c032a4 | ||
![]() |
293307e63d | ||
![]() |
2701522605 | ||
![]() |
98666855ad | ||
![]() |
adca9cf292 | ||
![]() |
fc20acd8cb | ||
![]() |
6744e86b62 | ||
![]() |
5ad202f482 | ||
![]() |
80edb3b8f2 | ||
![]() |
3bc8c80422 | ||
![]() |
4ac19ef8da | ||
![]() |
797bce2eac | ||
![]() |
807e80780d | ||
![]() |
a58ca80fc9 | ||
![]() |
4158bf1663 | ||
![]() |
cd0c594efb | ||
![]() |
648d4d961d | ||
![]() |
9bca6f77d6 | ||
![]() |
c33718c39d | ||
![]() |
19b51a4a69 | ||
![]() |
f9e5bc43c6 | ||
![]() |
42383948b7 | ||
![]() |
5f8a1723ba | ||
![]() |
b8086cb509 | ||
![]() |
e2cd0d1246 | ||
![]() |
9fbb9ac957 | ||
![]() |
f64439dab9 | ||
![]() |
fe423d0b46 | ||
![]() |
5018b0e9ff | ||
![]() |
8b0a650631 | ||
![]() |
81076d9c43 | ||
![]() |
b610af30ab | ||
![]() |
bbc10cd3db | ||
![]() |
6690139c66 | ||
![]() |
df9d5bfe25 | ||
![]() |
4a0dd31b2c | ||
![]() |
afbfacb462 | ||
![]() |
5d68e76b30 | ||
![]() |
246cc1479a | ||
![]() |
408cd0e037 | ||
![]() |
43884c791f | ||
![]() |
c15eccf49a | ||
![]() |
ddb159eec8 | ||
![]() |
af8edae1d3 | ||
![]() |
91585e1059 | ||
![]() |
d6a99d4354 | ||
![]() |
0d840b2c41 | ||
![]() |
0288a0f2b5 | ||
![]() |
fe7dc4902b | ||
![]() |
1caf380505 | ||
![]() |
628ce16e99 | ||
![]() |
f822b04a6f | ||
![]() |
a61747cd94 | ||
![]() |
86c97f5566 | ||
![]() |
31e633f55e | ||
![]() |
e3aa3e24f5 | ||
![]() |
b7396fdf8c | ||
![]() |
e8f0e31a27 | ||
![]() |
d759c6bc24 | ||
![]() |
f76d0d2f81 | ||
![]() |
ec8b02e1c1 | ||
![]() |
c27ac06f1b | ||
![]() |
24f8f9ca14 | ||
![]() |
8b8bbba85d | ||
![]() |
64be75142e | ||
![]() |
f2070bad08 | ||
![]() |
52a3b680a6 | ||
![]() |
735bfbae3b | ||
![]() |
9140234b2c | ||
![]() |
cbf35c276e | ||
![]() |
ab1b8572f3 | ||
![]() |
960de8647c | ||
![]() |
acf80417d1 | ||
![]() |
43a3db178f | ||
![]() |
f05123123c | ||
![]() |
2f73dac57a | ||
![]() |
a6087dd08f | ||
![]() |
b4d40fae3b | ||
![]() |
ad19dc0100 | ||
![]() |
d19c776ec3 | ||
![]() |
ccd792bf62 | ||
![]() |
8a55199d62 | ||
![]() |
9cf0a1ac26 | ||
![]() |
43620c280d | ||
![]() |
98ffb3bf9e | ||
![]() |
4cc4fb4d3c | ||
![]() |
1f9718a3c1 | ||
![]() |
16d9a3ba8b | ||
![]() |
a01fc5d72c | ||
![]() |
f4e777b8df | ||
![]() |
e8b55881bd | ||
![]() |
232dd34717 | ||
![]() |
e244109073 | ||
![]() |
e6324a2182 | ||
![]() |
46bc66d08c | ||
![]() |
73fe85018e | ||
![]() |
982d6921cb | ||
![]() |
bb28b76a5b | ||
![]() |
67fed0da9e | ||
![]() |
e3cf50b4c9 | ||
![]() |
f72bb31b8e | ||
![]() |
001f13398c | ||
![]() |
dcfe93e4a1 | ||
![]() |
d3e7b5838f | ||
![]() |
8788d109e3 | ||
![]() |
8b1839ff1b | ||
![]() |
9f46e1960e | ||
![]() |
e93a619859 | ||
![]() |
287ba7055e | ||
![]() |
dfbec1f23a | ||
![]() |
55dedb4c4d | ||
![]() |
9c71b444c6 | ||
![]() |
e859b1c131 | ||
![]() |
6c4bd9cc10 | ||
![]() |
b50281f8d5 | ||
![]() |
2be0f5cedb | ||
![]() |
646a89d52a | ||
![]() |
fea71903de | ||
![]() |
0220d2b40f | ||
![]() |
c751c51b25 | ||
![]() |
8fedf78e03 | ||
![]() |
bd3c86e068 | ||
![]() |
46d459bd73 | ||
![]() |
d1feaad5a9 | ||
![]() |
b5b6c8f37a | ||
![]() |
067aaa798d | ||
![]() |
c85d7dcd7a | ||
![]() |
c1b1f1efd8 | ||
![]() |
68dcd21c4e | ||
![]() |
748484e129 | ||
![]() |
293e9988c7 | ||
![]() |
c390a295cd | ||
![]() |
bdf1f3c33d | ||
![]() |
a0b8685f7d | ||
![]() |
06fc25cf3b | ||
![]() |
18e76c5f12 | ||
![]() |
53e1bc5b83 | ||
![]() |
f3b77663f8 | ||
![]() |
fb25ea7cf9 | ||
![]() |
33dec9746a | ||
![]() |
079006e3ce | ||
![]() |
b32befe5df | ||
![]() |
91139005dc | ||
![]() |
9c53f8608a | ||
![]() |
7144491d0c | ||
![]() |
a9831ccf40 | ||
![]() |
fa3e18fe58 | ||
![]() |
08f29bacfd | ||
![]() |
5a6803551b | ||
![]() |
a5f612c85a | ||
![]() |
dab69249d0 | ||
![]() |
e1f0098164 | ||
![]() |
14428aaf49 | ||
![]() |
f9ebfcc467 | ||
![]() |
07446309d3 | ||
![]() |
d2de23481a | ||
![]() |
d8ead10c0f | ||
![]() |
6a38188602 | ||
![]() |
13884e9524 | ||
![]() |
1ff629e257 | ||
![]() |
67649a1746 | ||
![]() |
3a2f370c8c | ||
![]() |
6380608fa2 | ||
![]() |
4df53701a1 | ||
![]() |
3050b19366 | ||
![]() |
4c0a9b3797 | ||
![]() |
7850508cfe | ||
![]() |
dfbb36eb53 | ||
![]() |
e55fbe9159 | ||
![]() |
8a3af47b35 | ||
![]() |
11dc8cf982 | ||
![]() |
b91a3c16fc | ||
![]() |
abfe2bbe37 | ||
![]() |
f8bc330909 | ||
![]() |
999cf39aec | ||
![]() |
661a6563b0 | ||
![]() |
e33cf5b4ed | ||
![]() |
d401b6483c | ||
![]() |
5a855659b0 | ||
![]() |
e21e1b0b3d | ||
![]() |
232cb3ee7d | ||
![]() |
8bdefd85d4 | ||
![]() |
1719775ffc | ||
![]() |
86296e4066 | ||
![]() |
8c8c2ae271 | ||
![]() |
25f1674619 | ||
![]() |
29b3d6de3f | ||
![]() |
d6c76c9298 | ||
![]() |
b0168f46d7 | ||
![]() |
117990cd46 | ||
![]() |
6d238b382f | ||
![]() |
75fb384109 | ||
![]() |
e2a7a3686b | ||
![]() |
e29b42c4b1 | ||
![]() |
717806e821 | ||
![]() |
0a4f20b60c | ||
![]() |
90de8f3900 | ||
![]() |
09d4c727b1 | ||
![]() |
5a88c982cb | ||
![]() |
13a0e1d725 | ||
![]() |
7c06243d54 | ||
![]() |
ecd3b90300 | ||
![]() |
dc5a38ccba | ||
![]() |
406675f750 | ||
![]() |
a5e0572600 | ||
![]() |
3e5106525d | ||
![]() |
60b1e14e54 | ||
![]() |
31e667a421 | ||
![]() |
02428776a7 | ||
![]() |
7c1ab73f11 | ||
![]() |
8b5758fc37 | ||
![]() |
cb9eb8f67e | ||
![]() |
b496f13c3c | ||
![]() |
f21a0622b0 | ||
![]() |
5ddf8f2c34 | ||
![]() |
31655aace4 | ||
![]() |
32dca0799c | ||
![]() |
79cb90e642 | ||
![]() |
56bde906d9 | ||
![]() |
315af4cd5b | ||
![]() |
4abc72f05a | ||
![]() |
393aba90e9 | ||
![]() |
90624c03d2 | ||
![]() |
f75599805f | ||
![]() |
cc343fae9e | ||
![]() |
c22b299bed | ||
![]() |
28c806bfee | ||
![]() |
0bde71d4dd | ||
![]() |
aa51dcddc6 | ||
![]() |
8ca865e5aa | ||
![]() |
a9f1d2ac14 | ||
![]() |
018e5cba83 | ||
![]() |
bbcfee3ad6 | ||
![]() |
df52f37b69 | ||
![]() |
308ab4b4f5 | ||
![]() |
f07b6e28c1 | ||
![]() |
790fc92916 | ||
![]() |
bb5632c98d | ||
![]() |
879a73494b | ||
![]() |
93d80b8dfb | ||
![]() |
edf6a04a36 | ||
![]() |
b1662cdc1a | ||
![]() |
cec56e78bf | ||
![]() |
b0bfd0f56e | ||
![]() |
4312aceae7 | ||
![]() |
a646a59d8d | ||
![]() |
c9eafe1db3 | ||
![]() |
270ba9d196 | ||
![]() |
7300d252f8 | ||
![]() |
9b73cc16e6 | ||
![]() |
b7da57d6d1 | ||
![]() |
dee78cd503 | ||
![]() |
383e1d5245 | ||
![]() |
2ec9329f2e | ||
![]() |
15fc2c01bd | ||
![]() |
4fdd9b4710 | ||
![]() |
7765c464f3 | ||
![]() |
43eba0aa1d | ||
![]() |
e097cd2daa | ||
![]() |
ad6b5719d2 | ||
![]() |
5d344e3193 | ||
![]() |
0cd86282d2 | ||
![]() |
6b8d00decf | ||
![]() |
85aae4d408 | ||
![]() |
92b0a3abb2 | ||
![]() |
444a48f2a1 | ||
![]() |
039b44b07a | ||
![]() |
d7ed33c351 | ||
![]() |
0edff4665c | ||
![]() |
66b2fee823 | ||
![]() |
2139e31754 | ||
![]() |
3752d35229 | ||
![]() |
9a90e80da1 | ||
![]() |
5d3ec771c4 | ||
![]() |
6785d17ab3 | ||
![]() |
99a0415235 | ||
![]() |
0fe3f50d93 | ||
![]() |
06647a4cf6 | ||
![]() |
66b1e4a327 | ||
![]() |
a5e1a8116f | ||
![]() |
0bf77e1737 | ||
![]() |
038f0a5135 | ||
![]() |
e7d4dde9d9 | ||
![]() |
96dbbcff3e | ||
![]() |
1479742fe8 | ||
![]() |
45bebd898d | ||
![]() |
2f99cf81fc | ||
![]() |
0aa5450dc6 | ||
![]() |
5cdca0b7c1 | ||
![]() |
58ed857724 | ||
![]() |
66536a59a9 | ||
![]() |
35ab292c9f | ||
![]() |
341f1e915f | ||
![]() |
28da9da752 | ||
![]() |
6ce9330d3b | ||
![]() |
c251ee2d22 | ||
![]() |
cee5137603 | ||
![]() |
fd5c6d0024 | ||
![]() |
3d5a962332 | ||
![]() |
f096b290a7 | ||
![]() |
5a9281ece4 | ||
![]() |
b1367ec0a9 | ||
![]() |
e73d919ed7 | ||
![]() |
9bcb5e73ba | ||
![]() |
87f7510007 | ||
![]() |
814e3d8ee7 | ||
![]() |
d2cc6cca36 | ||
![]() |
ea5a95d536 | ||
![]() |
a845eb3942 | ||
![]() |
f87fb34943 | ||
![]() |
4dc9c1f433 | ||
![]() |
d885a63c7d | ||
![]() |
62833f2fa9 | ||
![]() |
e6ff69d6fc | ||
![]() |
176f840cb6 | ||
![]() |
76f06170ad | ||
![]() |
b6561cd940 | ||
![]() |
878d7070a4 | ||
![]() |
5f71198c88 | ||
![]() |
8d941913aa | ||
![]() |
599571e6ea | ||
![]() |
90709ef4d0 | ||
![]() |
378aa1026d | ||
![]() |
4fb1761fa5 | ||
![]() |
254193eb8c | ||
![]() |
d92e260ffd | ||
![]() |
8f5a5e4d57 | ||
![]() |
d0d9535d2f | ||
![]() |
df1409af76 | ||
![]() |
cfe34733e9 | ||
![]() |
e916cbe762 | ||
![]() |
a8a4142cef | ||
![]() |
3b3fffe838 | ||
![]() |
d32b8a1e71 | ||
![]() |
05e547edb5 | ||
![]() |
1b25430fe7 | ||
![]() |
278dc6880c | ||
![]() |
0bd1761077 | ||
![]() |
b1ae964ca3 | ||
![]() |
56cbb9e9af | ||
![]() |
70558574a8 | ||
![]() |
dab8375f5e | ||
![]() |
ccd9d05ac7 | ||
![]() |
69a045c144 | ||
![]() |
8f7b609c7c | ||
![]() |
0019dd6c7a | ||
![]() |
305a99afc8 | ||
![]() |
eec23d9640 | ||
![]() |
76f28ef94a | ||
![]() |
3b89d96553 | ||
![]() |
0fba78f885 | ||
![]() |
ee38944cf9 | ||
![]() |
c24cbcfbc0 | ||
![]() |
28c01f0a43 | ||
![]() |
182f671e35 | ||
![]() |
788495aac8 | ||
![]() |
7cbeb821f5 | ||
![]() |
36901194dc | ||
![]() |
58071007bd | ||
![]() |
07bafdf416 | ||
![]() |
f7bb5ec500 | ||
![]() |
b92114fec6 | ||
![]() |
fe9bb2a712 | ||
![]() |
81996f8051 | ||
![]() |
a0a976c345 | ||
![]() |
9315f36f16 | ||
![]() |
cdc03836d2 | ||
![]() |
a14e95ad6c | ||
![]() |
dd230f720f | ||
![]() |
fa781de76f | ||
![]() |
377e085aa0 | ||
![]() |
3642b32ed6 | ||
![]() |
8a6ecf005b | ||
![]() |
6866fdbdf5 | ||
![]() |
78bc4060b3 | ||
![]() |
16b901ea9e | ||
![]() |
26a3974477 | ||
![]() |
9a10d6fe6c | ||
![]() |
eb72def6d0 | ||
![]() |
3fe2a2e3b0 | ||
![]() |
d22d0f67b5 | ||
![]() |
e56e944309 | ||
![]() |
2d853d8d28 | ||
![]() |
e5d086dace | ||
![]() |
eccdd725b7 | ||
![]() |
284e0b4bf5 | ||
![]() |
47becb2721 | ||
![]() |
0b64e26235 | ||
![]() |
d90db8157c | ||
![]() |
11da530151 | ||
![]() |
c067c67e34 | ||
![]() |
89913ad4d7 | ||
![]() |
b73f34ad8c | ||
![]() |
17cf68d8a5 | ||
![]() |
5c1795ee03 | ||
![]() |
19a8480a88 | ||
![]() |
e0e80d2ea8 | ||
![]() |
adab2326ed | ||
![]() |
4ef629950d | ||
![]() |
39197df0c7 | ||
![]() |
1d3d6f0ea1 | ||
![]() |
9272ffa52c | ||
![]() |
187e5864ac | ||
![]() |
e0711248a0 | ||
![]() |
bbbcf0502e | ||
![]() |
0498fac291 | ||
![]() |
fa007148da | ||
![]() |
7e69e5704a | ||
![]() |
8579229797 | ||
![]() |
59d8f4c1cf | ||
![]() |
d05942ebe1 | ||
![]() |
1b9457bdff | ||
![]() |
05f2848d41 | ||
![]() |
ab3a28e50d | ||
![]() |
121daa81cc | ||
![]() |
17e1d75238 | ||
![]() |
597cdf4398 | ||
![]() |
215ca7806e | ||
![]() |
92f0d28d24 | ||
![]() |
d964a0c375 | ||
![]() |
332f04fdfe | ||
![]() |
291ea3bfb0 | ||
![]() |
51dbef9060 | ||
![]() |
d6f771f6c3 | ||
![]() |
d659ee2880 | ||
![]() |
7b37a5e611 | ||
![]() |
b99f2a23a8 | ||
![]() |
a54d8af051 | ||
![]() |
62a309cba6 | ||
![]() |
b7c0e4725d | ||
![]() |
53a21fb5fe | ||
![]() |
5802f7c2c5 | ||
![]() |
3c2640c90d | ||
![]() |
6f2ea9e893 | ||
![]() |
8b06bdfc29 | ||
![]() |
b6a5e60b68 | ||
![]() |
e16857457c | ||
![]() |
20663ec854 | ||
![]() |
f0166dd18f | ||
![]() |
5b8fe2393e | ||
![]() |
b08408c3c7 | ||
![]() |
060f8ece8a | ||
![]() |
eedc50b4fe | ||
![]() |
d7a636e4de | ||
![]() |
9e9319f117 | ||
![]() |
928162798f | ||
![]() |
b5b71a2dc6 | ||
![]() |
033b792b54 | ||
![]() |
7ab53edbbf | ||
![]() |
624c3bf223 | ||
![]() |
cf28312740 | ||
![]() |
a1e2beb1cf | ||
![]() |
4af9ab0bcb | ||
![]() |
8d3bde86e3 | ||
![]() |
7011a4fe07 | ||
![]() |
76f14fc4ba | ||
![]() |
923c0fee7a | ||
![]() |
b62680137e | ||
![]() |
82e39c9236 | ||
![]() |
1e69e98b92 |
@@ -1,102 +0,0 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
<SmellBaseline>
|
|
||||||
<ManuallySuppressedIssues>
|
|
||||||
<ID>ComplexMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
|
||||||
<ID>ComplexMethod:CommandState.kt$CommandState$ fun toVimNotation(): String</ID>
|
|
||||||
</ManuallySuppressedIssues>
|
|
||||||
<CurrentIssues>
|
|
||||||
<ID>ComplexCondition:CommandParser.kt$CommandParser$Character.isLetter(ch) || command.isEmpty() && "~<>@=#*&!".indexOf(ch) >= 0 || command.isNotEmpty() && ch == command[command.length - 1] && "<>".indexOf(ch) >= 0</ID>
|
|
||||||
<ID>ComplexMethod:CommandParser.kt$CommandParser$ @kotlin.jvm.Throws(ExException::class) fun parse(cmd: String): ExCommand</ID>
|
|
||||||
<ID>ComplexMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>ComplexMethod:NerdTree.kt$NerdTree$private fun registerCommands()</ID>
|
|
||||||
<ID>ComplexMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
|
||||||
<ID>ComplexMethod:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets( editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any> ): List<Int></ID>
|
|
||||||
<ID>ComplexMethod:SearchHelperKt.kt$// bounds are considered inside corresponding quotes fun checkInString(chars: CharSequence, currentPos: Int, str: Boolean): Boolean</ID>
|
|
||||||
<ID>ComplexMethod:SearchHighlightsHelper.kt$ private fun updateSearchHighlights( pattern: String?, shouldIgnoreSmartCase: Boolean, showHighlights: Boolean, initialOffset: Int, searchRange: LineRange?, forwards: Boolean, forceUpdate: Boolean ): Int</ID>
|
|
||||||
<ID>ComplexMethod:TabCloseHandler.kt$TabCloseHandler$ private fun getTabIndexToClose(arg: String, current: Int, last: Int): Int?</ID>
|
|
||||||
<ID>ComplexMethod:VimExchangeExtension.kt$VimExchangeExtension.Operator$private fun compareExchanges(x: Exchange, y: Exchange): ExchangeCompareResult</ID>
|
|
||||||
<ID>ComplexMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
|
||||||
<ID>ComplexMethod:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun isEnabled(e: AnActionEvent): Boolean</ID>
|
|
||||||
<ID>LongMethod:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
|
||||||
<ID>LongMethod:CommandParser.kt$CommandParser$ @kotlin.jvm.Throws(ExException::class) fun parse(cmd: String): ExCommand</ID>
|
|
||||||
<ID>LongMethod:HistoryHandler.kt$HistoryHandler$override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean</ID>
|
|
||||||
<ID>LongMethod:NerdTree.kt$NerdTree$private fun registerCommands()</ID>
|
|
||||||
<ID>LongMethod:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
|
||||||
<ID>LongMethod:PutGroup.kt$PutGroup$private fun prepareDocumentAndGetStartOffsets( editor: Editor, caret: Caret, typeInRegister: SelectionType, data: PutData, additionalData: Map<String, Any> ): List<Int></ID>
|
|
||||||
<ID>LongMethod:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
|
||||||
<ID>LoopWithTooManyJumpStatements:NerdTree.kt$NerdTree$while (true) { row++ val nextPath = tree.getPathForRow(row) ?: break val pathCount = nextPath.pathCount if (pathCount == currentPathCount) expectedRow = row if (pathCount < currentPathCount) break }</ID>
|
|
||||||
<ID>LoopWithTooManyJumpStatements:SearchHighlightsHelper.kt$for (project in projectManager.openProjects) { val current = FileEditorManager.getInstance(project).selectedTextEditor ?: continue // [VERSION UPDATE] 202+ Use editors val editors = EditorFactory.getInstance().getEditors(current.document, project) ?: continue for (editor in editors) { // Try to keep existing highlights if possible. Update if hlsearch has changed or if the pattern has changed. // Force update for the situations where the text is the same, but the ignore case values have changed. // E.g. Use `*` to search for a word (which ignores smartcase), then use `/<Up>` to search for the same pattern, // which will match smartcase. Or changing the smartcase/ignorecase settings if (shouldRemoveSearchHighlights(editor, pattern, showHighlights) || forceUpdate) { removeSearchHighlights(editor) } if (pattern == null) continue if (shouldAddAllSearchHighlights(editor, pattern, showHighlights)) { // hlsearch (+ incsearch/noincsearch) val startLine = searchRange?.startLine ?: 0 val endLine = searchRange?.endLine ?: -1 val results = SearchHelper.findAll(editor, pattern, startLine, endLine, shouldIgnoreCase(pattern, shouldIgnoreSmartCase)) if (results.isNotEmpty()) { currentMatchOffset = findClosestMatch(editor, results, initialOffset, forwards) highlightSearchResults(editor, pattern, results, currentMatchOffset) } editor.vimLastSearch = pattern } else if (shouldAddCurrentMatchSearchHighlight(pattern, showHighlights, initialOffset)) { // nohlsearch + incsearch val searchOptions = EnumSet.of(SearchOptions.WHOLE_FILE) if (wrapscan.isSet) searchOptions.add(SearchOptions.WRAP) if (shouldIgnoreSmartCase) searchOptions.add(SearchOptions.IGNORE_SMARTCASE) if (!forwards) searchOptions.add(SearchOptions.BACKWARDS) val result = SearchHelper.findPattern(editor, pattern, initialOffset, 1, searchOptions) if (result != null) { currentMatchOffset = result.startOffset val results = listOf(result) highlightSearchResults(editor, pattern, results, currentMatchOffset) } } else if (shouldMaintainCurrentMatchOffset(pattern, initialOffset)) { // incsearch. If nothing has changed (e.g. we've edited offset values in `/foo/e+2`) make sure we return the // current match offset so the caret remains at the current incsarch match val offset = editor.vimIncsearchCurrentMatchOffset if (offset != null) { currentMatchOffset = offset } } } }</ID>
|
|
||||||
<ID>MagicNumber:ActionListHandler.kt$ActionListHandler$50</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$0.9f</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$1.75f</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$10</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$3</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$5</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$6</ID>
|
|
||||||
<ID>MagicNumber:AddBlockInlaysAction.kt$AddBlockInlaysAction$7</ID>
|
|
||||||
<ID>MagicNumber:AddInlineInlaysAction.kt$AddInlineInlaysAction$10</ID>
|
|
||||||
<ID>MagicNumber:AddInlineInlaysAction.kt$AddInlineInlaysAction$20</ID>
|
|
||||||
<ID>MagicNumber:AddInlineInlaysAction.kt$AddInlineInlaysAction$5</ID>
|
|
||||||
<ID>MagicNumber:AddInlineInlaysAction.kt$AddInlineInlaysAction$7</ID>
|
|
||||||
<ID>MagicNumber:BufferListHandler.kt$3</ID>
|
|
||||||
<ID>MagicNumber:CmdHandler.kt$CmdHandler$11</ID>
|
|
||||||
<ID>MagicNumber:CmdHandler.kt$CmdHandler$12</ID>
|
|
||||||
<ID>MagicNumber:CommandBuilder.kt$CommandBuilder$10</ID>
|
|
||||||
<ID>MagicNumber:CommandBuilder.kt$CommandBuilder$999999999</ID>
|
|
||||||
<ID>MagicNumber:CommandParser.kt$CommandParser$10</ID>
|
|
||||||
<ID>MagicNumber:CommandParser.kt$CommandParser$3</ID>
|
|
||||||
<ID>MagicNumber:ConfigurationMigrators.kt$Version 6 to 7 config migration$6</ID>
|
|
||||||
<ID>MagicNumber:ConfigurationMigrators.kt$Version 6 to 7 config migration$7</ID>
|
|
||||||
<ID>MagicNumber:ExKeyBindings.kt$ExKeyBindings$0x05</ID>
|
|
||||||
<ID>MagicNumber:ExKeyBindings.kt$ExKeyBindings$0x08</ID>
|
|
||||||
<ID>MagicNumber:HistoryHandler.kt$HistoryHandler$7</ID>
|
|
||||||
<ID>MagicNumber:JumpsHandler.kt$JumpsHandler$200</ID>
|
|
||||||
<ID>MagicNumber:JumpsHandler.kt$JumpsHandler$3</ID>
|
|
||||||
<ID>MagicNumber:JumpsHandler.kt$JumpsHandler$5</ID>
|
|
||||||
<ID>MagicNumber:MarksHandler.kt$MarksHandler$200</ID>
|
|
||||||
<ID>MagicNumber:MarksHandler.kt$MarksHandler$3</ID>
|
|
||||||
<ID>MagicNumber:MarksHandler.kt$MarksHandler$5</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$100</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$1000</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$19</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$20</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$3</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$50</ID>
|
|
||||||
<ID>MagicNumber:OptionsManager.kt$OptionsManager$80</ID>
|
|
||||||
<ID>MagicNumber:ProcessExEntryAction.kt$ProcessExEntryAction$0x0a</ID>
|
|
||||||
<ID>MagicNumber:RegistersHandler.kt$RegistersHandler$200</ID>
|
|
||||||
<ID>MagicNumber:SearchHelperKt.kt$3</ID>
|
|
||||||
<ID>MagicNumber:SelectLastFileHandler.kt$SelectLastFileHandler$999</ID>
|
|
||||||
<ID>MagicNumber:SelectionType.kt$SelectionType.BLOCK_WISE$3</ID>
|
|
||||||
<ID>MagicNumber:ShiftLeftHandler.kt$ShiftLeftHandler$31</ID>
|
|
||||||
<ID>MagicNumber:ShiftRightHandler.kt$ShiftRightHandler$31</ID>
|
|
||||||
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$3</ID>
|
|
||||||
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$4</ID>
|
|
||||||
<ID>MatchingDeclarationName:CommandDefinition.kt$CommandName</ID>
|
|
||||||
<ID>MaxLineLength:EditorDataContext.kt$EditorDataContext$class</ID>
|
|
||||||
<ID>MaxLineLength:ExBeanClass.kt$ExBeanClass$logger<ExBeanClass>().error("IdeaVim doesn't accept contributions to `vimActions` extension points. Please create a plugin using `VimExtension`. Plugin to blame: ${this.pluginDescriptor.pluginId}")</ID>
|
|
||||||
<ID>MaxLineLength:NotificationService.kt$NotificationService$notification.addAction(AppendToIdeaVimRcAction(notification, "set clipboard+=ideaput", "ideaput") { OptionsManager.clipboard.append(ClipboardOptionsData.ideaput) })</ID>
|
|
||||||
<ID>MaxLineLength:NotificationService.kt$NotificationService.AppendToIdeaVimRcAction$private inner</ID>
|
|
||||||
<ID>MaxLineLength:NotificationService.kt$NotificationService.AppendToIdeaVimRcAction$val successNotification = Notification(IDEAVIM_NOTIFICATION_ID, IDEAVIM_NOTIFICATION_TITLE, "<code>$optionName</code> is enabled", NotificationType.INFORMATION)</ID>
|
|
||||||
<ID>MaxLineLength:OptionsManager.kt$OptionsManager$val clipboard = addOption(ListOption(ClipboardOptionsData.name, ClipboardOptionsData.abbr, arrayOf(ClipboardOptionsData.ideaput, "autoselect,exclude:cons\\|linux"), null))</ID>
|
|
||||||
<ID>MaxLineLength:ReplaceWithRegister.kt$ReplaceWithRegister.Operator$val visualSelection = PutData.VisualSelection(mapOf(editor.caretModel.primaryCaret to VimSelection.create(range.startOffset, range.endOffset - 1, selectionType, editor)), selectionType)</ID>
|
|
||||||
<ID>MaxLineLength:StatisticReporter.kt$StatisticReporter$val url = "https://plugins.jetbrains.com/plugins/list?pluginId=${VimPlugin.getPluginId().idString}&build=$buildNumber&pluginVersion=$version&os=$os&uuid=$uid"</ID>
|
|
||||||
<ID>MemberNameEqualsClassName:Ranges.kt$Ranges$private val ranges: MutableList<Range> = mutableListOf()</ID>
|
|
||||||
<ID>NestedBlockDepth:OptionsManager.kt$OptionsManager$ fun parseOptionLine(editor: Editor?, args: String, failOnBad: Boolean): Boolean</ID>
|
|
||||||
<ID>ReturnCount:CmdHandler.kt$CmdHandler$private fun addAlias(cmd: ExCommand, editor: Editor?): Boolean</ID>
|
|
||||||
<ID>ReturnCount:ExRanges.kt$Range.Companion$ @JvmStatic fun createRange(str: String, offset: Int, move: Boolean): Array<Range>?</ID>
|
|
||||||
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.AllOccurrencesHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
|
||||||
<ID>ReturnCount:VimMultipleCursorsExtension.kt$VimMultipleCursorsExtension.NextOccurrenceHandler$override fun executeInWriteAction(editor: Editor, context: DataContext)</ID>
|
|
||||||
<ID>ReturnCount:VimShortcutKeyAction.kt$VimShortcutKeyAction$private fun isEnabled(e: AnActionEvent): Boolean</ID>
|
|
||||||
<ID>ReturnCount:VisualMotionGroup.kt$VisualMotionGroup$private fun seemsLikeBlockMode(editor: Editor): Boolean</ID>
|
|
||||||
<ID>ThrowsCount:CommandHandler.kt$CommandHandler$private fun checkArgs(cmd: ExCommand)</ID>
|
|
||||||
<ID>TooGenericExceptionThrown:CommandParser.kt$CommandParser$throw RuntimeException("Cannot create an ex command: $handlerHolder")</ID>
|
|
||||||
<ID>TooManyFunctions:CommandBuilder.kt$CommandBuilder</ID>
|
|
||||||
<ID>TooManyFunctions:CommandState.kt$CommandState</ID>
|
|
||||||
<ID>TooManyFunctions:PutGroup.kt$PutGroup</ID>
|
|
||||||
<ID>TooManyFunctions:Ranges.kt$Ranges</ID>
|
|
||||||
<ID>TooManyFunctions:SearchHighlightsHelper.kt$com.maddyhome.idea.vim.helper.SearchHighlightsHelper.kt</ID>
|
|
||||||
<ID>TooManyFunctions:VisualGroup.kt$com.maddyhome.idea.vim.group.visual.VisualGroup.kt</ID>
|
|
||||||
<ID>TooManyFunctions:VisualMotionGroup.kt$VisualMotionGroup</ID>
|
|
||||||
</CurrentIssues>
|
|
||||||
</SmellBaseline>
|
|
@@ -1,31 +0,0 @@
|
|||||||
formatting:
|
|
||||||
Indentation:
|
|
||||||
indentSize: 2
|
|
||||||
continuationIndentSize: 8
|
|
||||||
ParameterListWrapping:
|
|
||||||
indentSize: 8
|
|
||||||
complexity:
|
|
||||||
LongParameterList:
|
|
||||||
functionThreshold: 12
|
|
||||||
NestedBlockDepth:
|
|
||||||
threshold: 6
|
|
||||||
ComplexCondition:
|
|
||||||
threshold: 6
|
|
||||||
ComplexMethod:
|
|
||||||
threshold: 20
|
|
||||||
exceptions:
|
|
||||||
TooGenericExceptionCaught:
|
|
||||||
active: false
|
|
||||||
naming:
|
|
||||||
ClassNaming:
|
|
||||||
excludes: "**/ConfigurationMigrators.kt, **/VersionDetectors.kt"
|
|
||||||
performance:
|
|
||||||
SpreadOperator:
|
|
||||||
active: false
|
|
||||||
style:
|
|
||||||
ForbiddenComment:
|
|
||||||
active: false
|
|
||||||
MaxLineLength:
|
|
||||||
maxLineLength: 160
|
|
||||||
ReturnCount:
|
|
||||||
max: 5
|
|
67
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ master ]
|
||||||
|
schedule:
|
||||||
|
- cron: '44 12 * * 4'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'java' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||||
|
# Learn more:
|
||||||
|
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
42
.github/workflows/mergePr.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
|
||||||
|
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
|
||||||
|
|
||||||
|
name: Update Changelog On PR
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [ closed ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
if: github.event.pull_request.merged == true
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 50
|
||||||
|
- name: Set up JDK 11
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'adopt'
|
||||||
|
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||||
|
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||||
|
|
||||||
|
- name: Update authors
|
||||||
|
id: update_authors
|
||||||
|
run: ./gradlew updateMergedPr -PprId=${{ github.event.number }}
|
||||||
|
env:
|
||||||
|
GITHUB_OAUTH: ${{ secrets.AUTOMATION_TOKEN }}
|
||||||
|
|
||||||
|
- name: Commit changes
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
with:
|
||||||
|
branch: master
|
||||||
|
commit_message: Update changelog after merging PR
|
||||||
|
commit_user_name: Alex Plate
|
||||||
|
commit_user_email: aleksei.plate@jetbrains.com
|
||||||
|
commit_author: Alex Plate <aleksei.plate@jetbrains.com>
|
||||||
|
file_pattern: CHANGES.md
|
77
.github/workflows/runUiTests.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
name: Run UI Tests
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 12 * * *'
|
||||||
|
jobs:
|
||||||
|
build-for-ui-test-mac-os:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v2.1.0
|
||||||
|
with:
|
||||||
|
distribution: zulu
|
||||||
|
java-version: 11
|
||||||
|
- name: Setup FFmpeg
|
||||||
|
uses: FedericoCarboni/setup-ffmpeg@v1
|
||||||
|
with:
|
||||||
|
# Not strictly necessary, but it may prevent rate limit
|
||||||
|
# errors especially on GitHub-hosted macos machines.
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Build Plugin
|
||||||
|
run: gradle :buildPlugin
|
||||||
|
- name: Run Idea
|
||||||
|
run: |
|
||||||
|
mkdir -p build/reports
|
||||||
|
gradle :runIdeForUiTests > build/reports/idea.log &
|
||||||
|
- name: Wait for Idea started
|
||||||
|
uses: jtalk/url-health-check-action@1.5
|
||||||
|
with:
|
||||||
|
url: http://127.0.0.1:8082
|
||||||
|
max-attempts: 20
|
||||||
|
retry-delay: 10s
|
||||||
|
- name: Tests
|
||||||
|
run: gradle :testUi
|
||||||
|
- name: Move video
|
||||||
|
if: ${{ failure() }}
|
||||||
|
run: mv video build/reports
|
||||||
|
- name: Save fails report
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: ui-test-fails-report-mac
|
||||||
|
path: |
|
||||||
|
build/reports
|
||||||
|
# build-for-ui-test-linux:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v2
|
||||||
|
# - name: Setup Java
|
||||||
|
# uses: actions/setup-java@v2.1.0
|
||||||
|
# with:
|
||||||
|
# distribution: zulu
|
||||||
|
# java-version: 11
|
||||||
|
# - name: Build Plugin
|
||||||
|
# run: gradle :buildPlugin
|
||||||
|
# - name: Run Idea
|
||||||
|
# run: |
|
||||||
|
# export DISPLAY=:99.0
|
||||||
|
# Xvfb -ac :99 -screen 0 1920x1080x16 &
|
||||||
|
# mkdir -p build/reports
|
||||||
|
# gradle :runIdeForUiTests #> build/reports/idea.log
|
||||||
|
# - name: Wait for Idea started
|
||||||
|
# uses: jtalk/url-health-check-action@1.5
|
||||||
|
# with:
|
||||||
|
# url: http://127.0.0.1:8082
|
||||||
|
# max-attempts: 15
|
||||||
|
# retry-delay: 30s
|
||||||
|
# - name: Tests
|
||||||
|
# run: gradle :testUi
|
||||||
|
# - name: Save fails report
|
||||||
|
# if: ${{ failure() }}
|
||||||
|
# uses: actions/upload-artifact@v2
|
||||||
|
# with:
|
||||||
|
# name: ui-test-fails-report-linux
|
||||||
|
# path: |
|
||||||
|
# ui-test-example/build/reports
|
49
.github/workflows/updateAuthors.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
|
||||||
|
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
|
||||||
|
|
||||||
|
name: Update Authors
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 300
|
||||||
|
- name: Set up JDK 11
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'adopt'
|
||||||
|
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||||
|
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||||
|
|
||||||
|
- uses: nrwl/last-successful-commit-action@v1
|
||||||
|
id: last_successful_commit
|
||||||
|
with:
|
||||||
|
branch: 'master'
|
||||||
|
workflow_id: 'updateAuthors.yml'
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Update authors
|
||||||
|
id: update_authors
|
||||||
|
run: ./gradlew updateAuthors --stacktrace
|
||||||
|
env:
|
||||||
|
SUCCESS_COMMIT: ${{ steps.last_successful_commit.outputs.commit_hash }}
|
||||||
|
GITHUB_OAUTH: ${{ secrets.AUTOMATION_TOKEN }}
|
||||||
|
|
||||||
|
- name: Commit changes
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
with:
|
||||||
|
commit_message: Add ${{ steps.update_authors.outputs.authors }} to contributors list
|
||||||
|
commit_user_name: Alex Plate
|
||||||
|
commit_user_email: aleksei.plate@jetbrains.com
|
||||||
|
commit_author: Alex Plate <aleksei.plate@jetbrains.com>
|
||||||
|
file_pattern: AUTHORS.md
|
47
.github/workflows/updateChangelog.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
|
||||||
|
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
|
||||||
|
|
||||||
|
name: Update Changelog
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 300
|
||||||
|
- name: Set up JDK 11
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'adopt'
|
||||||
|
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||||
|
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||||
|
|
||||||
|
- uses: nrwl/last-successful-commit-action@v1
|
||||||
|
id: last_successful_commit
|
||||||
|
with:
|
||||||
|
branch: 'master'
|
||||||
|
workflow_id: 'updateChangelog.yml'
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Update changelog
|
||||||
|
run: ./gradlew updateChangelog
|
||||||
|
env:
|
||||||
|
SUCCESS_COMMIT: ${{ steps.last_successful_commit.outputs.commit_hash }}
|
||||||
|
|
||||||
|
- name: Commit changes
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
with:
|
||||||
|
commit_message: Update changelog
|
||||||
|
commit_user_name: Alex Plate
|
||||||
|
commit_user_email: aleksei.plate@jetbrains.com
|
||||||
|
commit_author: Alex Plate <aleksei.plate@jetbrains.com>
|
||||||
|
file_pattern: CHANGES.md
|
37
.github/workflows/updateFormatting.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
|
||||||
|
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
|
||||||
|
|
||||||
|
name: Update Formatting
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 0'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 50
|
||||||
|
- name: Set up JDK 11
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '11'
|
||||||
|
distribution: 'adopt'
|
||||||
|
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||||
|
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||||
|
|
||||||
|
- name: Format files
|
||||||
|
run: ./gradlew ktlintFormat
|
||||||
|
|
||||||
|
- name: Commit changes
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
|
with:
|
||||||
|
commit_message: Update formatting
|
||||||
|
commit_user_name: Alex Plate
|
||||||
|
commit_user_email: aleksei.plate@jetbrains.com
|
||||||
|
commit_author: Alex Plate <aleksei.plate@jetbrains.com>
|
7
.gitignore
vendored
@@ -8,6 +8,7 @@
|
|||||||
!/.idea/inspectionProfiles
|
!/.idea/inspectionProfiles
|
||||||
!/.idea/fileTemplates
|
!/.idea/fileTemplates
|
||||||
!/.idea/runConfigurations
|
!/.idea/runConfigurations
|
||||||
|
!/.idea/codeStyles
|
||||||
|
|
||||||
/build/
|
/build/
|
||||||
/out/
|
/out/
|
||||||
@@ -18,3 +19,9 @@
|
|||||||
.teamcity/.idea
|
.teamcity/.idea
|
||||||
.teamcity/target
|
.teamcity/target
|
||||||
.teamcity/*.iml
|
.teamcity/*.iml
|
||||||
|
|
||||||
|
# Generated by gradle task "generateGrammarSource"
|
||||||
|
src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated
|
||||||
|
|
||||||
|
# Created by github automation
|
||||||
|
settings.xml
|
||||||
|
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "doc"]
|
|
||||||
path = doc
|
|
||||||
url = https://github.com/JetBrains/ideavim.wiki.git
|
|
196
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<option name="AUTODETECT_INDENTS" value="false" />
|
||||||
|
<option name="OTHER_INDENT_OPTIONS">
|
||||||
|
<value>
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<JavaCodeStyleSettings>
|
||||||
|
<option name="FIELD_NAME_PREFIX" value="my" />
|
||||||
|
<option name="STATIC_FIELD_NAME_PREFIX" value="our" />
|
||||||
|
</JavaCodeStyleSettings>
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||||
|
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||||
|
<option name="ALLOW_TRAILING_COMMA" value="true" />
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
|
<ScalaCodeStyleSettings>
|
||||||
|
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
||||||
|
</ScalaCodeStyleSettings>
|
||||||
|
<ADDITIONAL_INDENT_OPTIONS fileType="rb">
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
</ADDITIONAL_INDENT_OPTIONS>
|
||||||
|
<codeStyleSettings language="CFML">
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||||
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
|
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||||
|
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="ECMA Script Level 4">
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
|
||||||
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
|
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||||
|
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||||
|
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||||
|
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||||
|
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="1" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="GSP">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="Groovy">
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
|
||||||
|
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
|
||||||
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
|
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||||
|
<option name="THROWS_LIST_WRAP" value="5" />
|
||||||
|
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||||
|
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||||
|
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||||
|
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||||
|
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FIELD_ANNOTATION_WRAP" value="0" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="HTML">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
<option name="TAB_SIZE" value="8" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JAVA">
|
||||||
|
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||||
|
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
|
||||||
|
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
|
||||||
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
|
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||||
|
<option name="THROWS_LIST_WRAP" value="5" />
|
||||||
|
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
|
||||||
|
<option name="THROWS_KEYWORD_WRAP" value="1" />
|
||||||
|
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
||||||
|
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||||
|
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||||
|
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FIELD_ANNOTATION_WRAP" value="0" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
<option name="TAB_SIZE" value="8" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JSON">
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JSP">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
<option name="TAB_SIZE" value="8" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="JavaScript">
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="ELSE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="WHILE_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="CATCH_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="FINALLY_ON_NEW_LINE" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||||
|
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
|
||||||
|
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
||||||
|
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||||
|
<option name="BINARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_WRAP" value="5" />
|
||||||
|
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
|
||||||
|
<option name="FOR_STATEMENT_WRAP" value="5" />
|
||||||
|
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
|
||||||
|
<option name="ASSIGNMENT_WRAP" value="1" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="1" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="1" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="1" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="Python">
|
||||||
|
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||||
|
<option name="PARENT_SETTINGS_INSTALLED" value="true" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="XML">
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="2" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
<option name="TAB_SIZE" value="8" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
<codeStyleSettings language="kotlin">
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
33
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -31,6 +31,39 @@
|
|||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="MoveVariableDeclarationIntoWhen" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
<inspection_tool class="MoveVariableDeclarationIntoWhen" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="PluginXmlI18n" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="PluginXmlI18n" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="SSBasedInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<replaceConfiguration name="IdeaVim run for each caret" description="Please use IdeaVim version of `runForEachCaret` function" suppressId="ideavimRunForEachCaret" problemDescriptor="Replace with IdeaVim version" text="$editor$.caretModel.runForEachCaret { $expr$ }" recursive="false" caseInsensitive="false" type="Kotlin" pattern_context="default" reformatAccordingToStyle="true" shortenFQN="false" replacement="$editor$.vimForEachCaret { $expr$ }">
|
||||||
|
<constraint name="__context__" within="" contains="" />
|
||||||
|
<constraint name="editor" within="" contains="" />
|
||||||
|
<constraint name="expr" minCount="0" maxCount="2147483647" within="" contains="" />
|
||||||
|
</replaceConfiguration>
|
||||||
|
<replaceConfiguration name="Use IdeaVim method instead of the fixture" uuid="0f74da52-7360-33ae-9b40-d771aa128de6" description="Use assertState and other functions instead of myFixture.checkResult. This function also preformes assertion in neovim" suppressId="IdeaVimAssertState" problemDescriptor="Use IdeaVim testing methods" text="$fixture$.$check$($data$)" recursive="false" caseInsensitive="false" type="Kotlin" pattern_context="default" reformatAccordingToStyle="true" shortenFQN="false" replacement="assertState($data$)">
|
||||||
|
<constraint name="__context__" within="" contains="" />
|
||||||
|
<constraint name="fixture" regexp="myFixture" nameOfExprType="CodeInsightTestFixture" within="" contains="" />
|
||||||
|
<constraint name="check" regexp="checkResult" within="" contains="" />
|
||||||
|
<constraint name="data" within="" contains="" />
|
||||||
|
</replaceConfiguration>
|
||||||
|
<replaceConfiguration name="Use IdeaVim method instead of the fixture" uuid="0f74da52-7360-33ae-9b40-d771aa128de6" text="$fixture$.$check$($fileName$, $text$)" recursive="false" caseInsensitive="false" type="Kotlin" pattern_context="default" reformatAccordingToStyle="true" shortenFQN="false" replacement="configureByText($text$)">
|
||||||
|
<constraint name="__context__" within="" contains="" />
|
||||||
|
<constraint name="fixture" regexp="myFixture" nameOfExprType="CodeInsightTestFixture" within="" contains="" />
|
||||||
|
<constraint name="check" regexp="configureByText" within="" contains="" />
|
||||||
|
<constraint name="text" within="" contains="" />
|
||||||
|
<constraint name="fileName" within="" contains="" />
|
||||||
|
</replaceConfiguration>
|
||||||
|
<replaceConfiguration name="Use IdeaVim method instead of the fixture" uuid="0f74da52-7360-33ae-9b40-d771aa128de6" text="$fixture$.$check$($data$)" recursive="false" caseInsensitive="false" type="JAVA" pattern_context="default" reformatAccordingToStyle="true" shortenFQN="true" replacement="assertState($data$)">
|
||||||
|
<constraint name="__context__" within="" contains="" />
|
||||||
|
<constraint name="fixture" regexp="myFixture" within="" contains="" />
|
||||||
|
<constraint name="check" regexp="checkResult" within="" contains="" />
|
||||||
|
<constraint name="data" within="" contains="" />
|
||||||
|
</replaceConfiguration>
|
||||||
|
<replaceConfiguration name="Use IdeaVim method instead of the fixture" uuid="0f74da52-7360-33ae-9b40-d771aa128de6" text="$fixture$.$configure$($first$, $second$)" recursive="false" caseInsensitive="false" type="JAVA" pattern_context="default" reformatAccordingToStyle="true" shortenFQN="true" replacement="configureByText($second$)">
|
||||||
|
<constraint name="__context__" within="" contains="" />
|
||||||
|
<constraint name="fixture" regexp="myFixture" within="" contains="" />
|
||||||
|
<constraint name="configure" regexp="configureByText" within="" contains="" />
|
||||||
|
<constraint name="first" within="" contains="" />
|
||||||
|
<constraint name="second" within="" contains="" />
|
||||||
|
</replaceConfiguration>
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="UnstableApiUsage" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
2
.idea/scopes/Copyright.xml
generated
@@ -1,3 +1,3 @@
|
|||||||
<component name="DependencyValidationManager">
|
<component name="DependencyValidationManager">
|
||||||
<scope name="Copyright" pattern="file[IdeaVIM.main]:com//*||file[IdeaVIM.test]:*/" />
|
<scope name="Copyright" pattern="(file[IdeaVIM.main]:*/||file[IdeaVIM.test]:*/)&&!file[IdeaVIM.main]:resources//*" />
|
||||||
</component>
|
</component>
|
20
.teamcity/_Self/Constants.kt
vendored
@@ -1,10 +1,20 @@
|
|||||||
package _Self
|
package _Self
|
||||||
|
|
||||||
object Constants {
|
object Constants {
|
||||||
const val DEFAULT = "default"
|
const val DEFAULT_CHANNEL = "default"
|
||||||
const val EAP = "eap"
|
const val EAP_CHANNEL = "eap"
|
||||||
const val DEV = "Dev"
|
const val DEV_CHANNEL = "Dev"
|
||||||
|
|
||||||
const val VERSION = "0.64"
|
const val VERSION = "1.9.3"
|
||||||
const val DEV_VERSION = "0.65"
|
const val DEV_VERSION = "1.10.0"
|
||||||
|
|
||||||
|
const val GITHUB_TESTS = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val LINTING_TESTS = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val NVIM_TESTS = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val PROPERTY_TESTS = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val LONG_RUNNING_TESTS = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val QODANA_TESTS = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val RELEASE = "2021.3"
|
||||||
|
const val RELEASE_DEV = "LATEST-EAP-SNAPSHOT"
|
||||||
|
const val RELEASE_EAP = "LATEST-EAP-SNAPSHOT"
|
||||||
}
|
}
|
||||||
|
32
.teamcity/_Self/Project.kt
vendored
@@ -1,42 +1,38 @@
|
|||||||
package _Self
|
package _Self
|
||||||
|
|
||||||
import _Self.buildTypes.GitHubPullRequests
|
import _Self.buildTypes.*
|
||||||
import _Self.buildTypes.Nvim
|
import _Self.subprojects.GitHub
|
||||||
import _Self.buildTypes.PluginVerifier
|
|
||||||
import _Self.buildTypes.PropertyBased
|
|
||||||
import _Self.buildTypes.Qodana
|
|
||||||
import _Self.buildTypes.TestsForIntelliJ20202
|
|
||||||
import _Self.buildTypes.TestsForIntelliJ20203
|
|
||||||
import _Self.buildTypes.TestsForIntelliJEAP
|
|
||||||
import _Self.subprojects.OldTests
|
import _Self.subprojects.OldTests
|
||||||
import _Self.subprojects.Releases
|
import _Self.subprojects.Releases
|
||||||
import _Self.vcsRoots.Branch_181
|
import _Self.vcsRoots.Branch_181
|
||||||
import _Self.vcsRoots.Branch_183
|
import _Self.vcsRoots.Branch_183
|
||||||
import _Self.vcsRoots.Branch_191_193
|
import _Self.vcsRoots.Branch_191_193
|
||||||
import _Self.vcsRoots.Branch_201
|
import _Self.vcsRoots.Branch_201
|
||||||
|
import _Self.vcsRoots.Branch_202
|
||||||
import _Self.vcsRoots.GitHubPullRequest
|
import _Self.vcsRoots.GitHubPullRequest
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
||||||
|
|
||||||
object Project : Project({
|
object Project : Project({
|
||||||
description = "Vim emulation plugin for the IntelliJ platform products"
|
description = "Vim emulation plugin for the IntelliJ platform products"
|
||||||
|
|
||||||
subProjects(Releases, OldTests)
|
subProjects(Releases, OldTests, GitHub)
|
||||||
|
|
||||||
// VCS roots
|
// VCS roots
|
||||||
vcsRoot(Branch_183)
|
vcsRoot(Branch_183)
|
||||||
vcsRoot(Branch_181)
|
vcsRoot(Branch_181)
|
||||||
vcsRoot(Branch_191_193)
|
vcsRoot(Branch_191_193)
|
||||||
vcsRoot(Branch_201)
|
vcsRoot(Branch_201)
|
||||||
|
vcsRoot(Branch_202)
|
||||||
vcsRoot(GitHubPullRequest)
|
vcsRoot(GitHubPullRequest)
|
||||||
|
|
||||||
// Builds
|
// Builds
|
||||||
buildType(GitHubPullRequests)
|
|
||||||
|
|
||||||
buildType(TestsForIntelliJ20202)
|
|
||||||
buildType(TestsForIntelliJ20203)
|
buildType(TestsForIntelliJ20203)
|
||||||
|
buildType(TestsForIntelliJ20211)
|
||||||
|
buildType(TestsForIntelliJ20212)
|
||||||
buildType(TestsForIntelliJEAP)
|
buildType(TestsForIntelliJEAP)
|
||||||
|
|
||||||
buildType(PropertyBased)
|
buildType(PropertyBased)
|
||||||
|
buildType(LongRunning)
|
||||||
|
|
||||||
buildType(Nvim)
|
buildType(Nvim)
|
||||||
buildType(PluginVerifier)
|
buildType(PluginVerifier)
|
||||||
@@ -53,17 +49,17 @@ object Project : Project({
|
|||||||
param("ebs-optimized", "false")
|
param("ebs-optimized", "false")
|
||||||
param("image-instances-limit", "")
|
param("image-instances-limit", "")
|
||||||
param("image-name-prefix", "BuildAgentsIdeaVim")
|
param("image-name-prefix", "BuildAgentsIdeaVim")
|
||||||
param("instance-type", "c5d.large")
|
param("instance-type", "c5d.xlarge")
|
||||||
param("key-pair-name", "teamcity-prod-pub")
|
param("key-pair-name", "teamcity-prod-pub")
|
||||||
param("profileId", "amazon-48")
|
param("profileId", "amazon-48")
|
||||||
param("security-group-ids", "sg-eda08696,sg-7332cf0f,")
|
param("security-group-ids", "sg-eda08696,sg-7332cf0f,")
|
||||||
param("source-id", "BuildAgentsIdeaVim")
|
param("source-id", "BuildAgentsIdeaVim")
|
||||||
param("spot-instance-price", "0.1")
|
param("spot-instance-price", "0.12")
|
||||||
param("subnet-id", "subnet-58839511")
|
param("subnet-id", "subnet-58839511")
|
||||||
param("use-spot-instances", "true")
|
param("use-spot-instances", "true")
|
||||||
param("user-tags", "project=idea-vim")
|
param("user-tags", "project=idea-vim")
|
||||||
param("instance-type", "c5d.xlarge")
|
param("key-pair-name", "")
|
||||||
param("spot-instance-price", "0.12")
|
param("spot-instance-price", "")
|
||||||
}
|
}
|
||||||
feature {
|
feature {
|
||||||
type = "CloudProfile"
|
type = "CloudProfile"
|
||||||
@@ -84,6 +80,10 @@ object Project : Project({
|
|||||||
param("system.cloud.profile_id", "amazon-48")
|
param("system.cloud.profile_id", "amazon-48")
|
||||||
param("terminate-idle-time", "15")
|
param("terminate-idle-time", "15")
|
||||||
param("total-work-time", "")
|
param("total-work-time", "")
|
||||||
|
param("user-script", "")
|
||||||
|
param("spot-fleet-config", "")
|
||||||
|
param("terminate-after-build", "true")
|
||||||
|
param("name", "Cloud Agents - Single Build")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
21
.teamcity/_Self/buildTypes/ActiveTests.kt
vendored
@@ -4,6 +4,8 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
|
sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
|
||||||
@@ -17,12 +19,12 @@ sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
|
|||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean check"
|
tasks = "clean check -x ktlintMainSourceSetCheck -x ktlintTestSourceSetCheck"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
@@ -38,8 +40,21 @@ sealed class ActiveTests(buildName: String, ijVersion: String) : BuildType({
|
|||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
object TestsForIntelliJEAP : ActiveTests("Tests for IntelliJ Latest EAP", "LATEST-EAP-SNAPSHOT")
|
object TestsForIntelliJEAP : ActiveTests("Tests for IntelliJ Latest EAP", "LATEST-EAP-SNAPSHOT")
|
||||||
|
object TestsForIntelliJ20212 : ActiveTests("Tests for IntelliJ 2021.2", "2021.2.2")
|
||||||
|
object TestsForIntelliJ20211 : ActiveTests("Tests for IntelliJ 2021.1", "2021.1")
|
||||||
object TestsForIntelliJ20203 : ActiveTests("Tests for IntelliJ 2020.3", "2020.3")
|
object TestsForIntelliJ20203 : ActiveTests("Tests for IntelliJ 2020.3", "2020.3")
|
||||||
object TestsForIntelliJ20202 : ActiveTests("Tests for IntelliJ 2020.2", "2020.2")
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import _Self.Constants.GITHUB_TESTS
|
||||||
import _Self.vcsRoots.GitHubPullRequest
|
import _Self.vcsRoots.GitHubPullRequest
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
@@ -10,20 +11,22 @@ import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.VcsTrigger
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.VcsTrigger
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object GitHubPullRequests : BuildType({
|
object GithubTests : Github("clean test", "Tests")
|
||||||
name = "GitHub Pull Requests"
|
|
||||||
description = "Test GitHub pull requests"
|
sealed class Github(command: String, desc: String) : BuildType({
|
||||||
|
name = "GitHub Pull Requests $desc"
|
||||||
|
description = "Test GitHub pull requests $desc"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.3")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", GITHUB_TESTS)
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.GitHubPullRequest)
|
root(GitHubPullRequest)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
branchFilter = """
|
branchFilter = """
|
||||||
+:*
|
+:*
|
||||||
-:<default>
|
-:<default>
|
||||||
@@ -32,7 +35,7 @@ object GitHubPullRequests : BuildType({
|
|||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean test"
|
tasks = command
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
42
.teamcity/_Self/buildTypes/LongRunning.kt
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import _Self.Constants.LONG_RUNNING_TESTS
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
|
object LongRunning : BuildType({
|
||||||
|
name = "Long running tests"
|
||||||
|
params {
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", LONG_RUNNING_TESTS)
|
||||||
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.AUTO
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean testLongRunning"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
vcs {
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirements {
|
||||||
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
|
}
|
||||||
|
})
|
19
.teamcity/_Self/buildTypes/Nvim.kt
vendored
@@ -1,10 +1,13 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import _Self.Constants.NVIM_TESTS
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.script
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object Nvim : BuildType({
|
object Nvim : BuildType({
|
||||||
@@ -13,7 +16,7 @@ object Nvim : BuildType({
|
|||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "LATEST-EAP-SNAPSHOT")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", NVIM_TESTS)
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
param("env.ideavim.nvim.path", "./nvim-linux64/bin/nvim")
|
param("env.ideavim.nvim.path", "./nvim-linux64/bin/nvim")
|
||||||
}
|
}
|
||||||
@@ -21,7 +24,7 @@ object Nvim : BuildType({
|
|||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -51,4 +54,16 @@ object Nvim : BuildType({
|
|||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
2
.teamcity/_Self/buildTypes/PluginVerifier.kt
vendored
@@ -16,7 +16,7 @@ object PluginVerifier : BuildType({
|
|||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
|
5
.teamcity/_Self/buildTypes/PropertyBased.kt
vendored
@@ -1,5 +1,6 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import _Self.Constants.PROPERTY_TESTS
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
@@ -10,14 +11,14 @@ object PropertyBased : BuildType({
|
|||||||
name = "Property based tests"
|
name = "Property based tests"
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "LATEST-EAP-SNAPSHOT")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", PROPERTY_TESTS)
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
|
38
.teamcity/_Self/buildTypes/Qodana.kt
vendored
@@ -1,23 +1,28 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import _Self.Constants.QODANA_TESTS
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.qodana
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.qodana
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.ScheduleTrigger
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object Qodana : BuildType({
|
object Qodana : BuildType({
|
||||||
name = "Qodana checks"
|
name = "Qodana checks"
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "LATEST-EAP-SNAPSHOT")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", QODANA_TESTS)
|
||||||
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -27,13 +32,42 @@ object Qodana : BuildType({
|
|||||||
failBuildOnErrors = ""
|
failBuildOnErrors = ""
|
||||||
codeInspectionXmlConfig = "Custom"
|
codeInspectionXmlConfig = "Custom"
|
||||||
codeInspectionCustomXmlConfigPath = ".idea/inspectionProfiles/Qodana.xml"
|
codeInspectionCustomXmlConfigPath = ".idea/inspectionProfiles/Qodana.xml"
|
||||||
|
reportAsTestsEnable = "true"
|
||||||
|
param("clonefinder-languages", "Java")
|
||||||
|
param("clonefinder-mode", "")
|
||||||
|
param("report-version", "")
|
||||||
|
param("clonefinder-languages-container", "Java Kotlin")
|
||||||
|
param("namesAndTagsCustom", "repo.labs.intellij.net/static-analyser/qodana")
|
||||||
|
param("clonefinder-queried-project", "src")
|
||||||
|
param("clonefinder-enable", "true")
|
||||||
|
param("clonefinder-reference-projects", "src")
|
||||||
|
param("yaml-configuration", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
triggers {
|
triggers {
|
||||||
vcs {
|
vcs {
|
||||||
|
enabled = false
|
||||||
branchFilter = ""
|
branchFilter = ""
|
||||||
}
|
}
|
||||||
|
schedule {
|
||||||
|
schedulingPolicy = weekly {
|
||||||
|
dayOfWeek = ScheduleTrigger.DAY.Tuesday
|
||||||
|
}
|
||||||
|
branchFilter = ""
|
||||||
|
triggerBuild = always()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
threshold = 0
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.DEFAULT_UNIT
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.MORE
|
||||||
|
compareTo = value()
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_FAILED_COUNT
|
||||||
|
param("metricKey", "QodanaProblemsTotal")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
requirements {
|
requirements {
|
||||||
|
45
.teamcity/_Self/buildTypes/Release.kt
vendored
@@ -1,13 +1,17 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
import _Self.Constants.DEFAULT
|
import _Self.Constants.DEFAULT_CHANNEL
|
||||||
import _Self.Constants.DEV
|
import _Self.Constants.DEV_CHANNEL
|
||||||
import _Self.Constants.EAP
|
import _Self.Constants.EAP_CHANNEL
|
||||||
|
import _Self.Constants.RELEASE
|
||||||
import _Self.Constants.VERSION
|
import _Self.Constants.VERSION
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.vcsLabeling
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
|
|
||||||
object Release : BuildType({
|
object Release : BuildType({
|
||||||
name = "Publish Release"
|
name = "Publish Release"
|
||||||
@@ -17,30 +21,55 @@ object Release : BuildType({
|
|||||||
buildNumberPattern = VERSION
|
buildNumberPattern = VERSION
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", RELEASE)
|
||||||
password(
|
password(
|
||||||
"env.ORG_GRADLE_PROJECT_publishToken",
|
"env.ORG_GRADLE_PROJECT_publishToken",
|
||||||
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
||||||
label = "Password"
|
label = "Password"
|
||||||
)
|
)
|
||||||
param("env.ORG_GRADLE_PROJECT_publishUsername", "Aleksei.Plate")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_publishChannels", "$DEFAULT,$EAP,$DEV")
|
param("env.ORG_GRADLE_PROJECT_publishChannels", "$DEFAULT_CHANNEL,$EAP_CHANNEL,$DEV_CHANNEL")
|
||||||
|
password(
|
||||||
|
"env.ORG_GRADLE_PROJECT_slackUrl",
|
||||||
|
"credentialsJSON:a8ab8150-e6f8-4eaf-987c-bcd65eac50b5",
|
||||||
|
label = "Slack Token"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean publishPlugin"
|
tasks = "clean publishPlugin slackNotification"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
features {
|
||||||
|
vcsLabeling {
|
||||||
|
vcsRootId = "${DslContext.settingsRoot.id}"
|
||||||
|
labelingPattern = "%system.build.number%"
|
||||||
|
successfulOnly = true
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.ARTIFACT_SIZE
|
||||||
|
threshold = 5
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.DIFF
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
26
.teamcity/_Self/buildTypes/ReleaseDev.kt
vendored
@@ -1,11 +1,14 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
import _Self.Constants.DEV
|
import _Self.Constants.DEV_CHANNEL
|
||||||
import _Self.Constants.DEV_VERSION
|
import _Self.Constants.DEV_VERSION
|
||||||
|
import _Self.Constants.RELEASE_DEV
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
||||||
|
|
||||||
object ReleaseDev : BuildType({
|
object ReleaseDev : BuildType({
|
||||||
@@ -16,22 +19,21 @@ object ReleaseDev : BuildType({
|
|||||||
buildNumberPattern = "$DEV_VERSION-dev.%build.counter%"
|
buildNumberPattern = "$DEV_VERSION-dev.%build.counter%"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", RELEASE_DEV)
|
||||||
password(
|
password(
|
||||||
"env.ORG_GRADLE_PROJECT_publishToken",
|
"env.ORG_GRADLE_PROJECT_publishToken",
|
||||||
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
||||||
label = "Password"
|
label = "Password"
|
||||||
)
|
)
|
||||||
param("env.ORG_GRADLE_PROJECT_publishUsername", "Aleksei.Plate")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_publishChannels", DEV)
|
param("env.ORG_GRADLE_PROJECT_publishChannels", DEV_CHANNEL)
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -47,9 +49,21 @@ object ReleaseDev : BuildType({
|
|||||||
schedule {
|
schedule {
|
||||||
enabled = true
|
enabled = true
|
||||||
schedulingPolicy = daily {
|
schedulingPolicy = daily {
|
||||||
hour = 22
|
hour = 2
|
||||||
}
|
}
|
||||||
branchFilter = ""
|
branchFilter = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.ARTIFACT_SIZE
|
||||||
|
threshold = 5
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.DIFF
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
34
.teamcity/_Self/buildTypes/ReleaseEap.kt
vendored
@@ -1,33 +1,33 @@
|
|||||||
package _Self.buildTypes
|
package _Self.buildTypes
|
||||||
|
|
||||||
import _Self.Constants.EAP
|
import _Self.Constants.DEV_VERSION
|
||||||
import _Self.Constants.VERSION
|
import _Self.Constants.EAP_CHANNEL
|
||||||
|
import _Self.Constants.RELEASE_EAP
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
import jetbrains.buildServer.configs.kotlin.v2019_2.DslContext
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.vcsLabeling
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.vcsLabeling
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.ScheduleTrigger
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.schedule
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
|
|
||||||
object ReleaseEap : BuildType({
|
object ReleaseEap : BuildType({
|
||||||
name = "Publish EAP Build"
|
name = "Publish EAP Build"
|
||||||
description = "Build and publish EAP of IdeaVim plugin"
|
description = "Build and publish EAP of IdeaVim plugin"
|
||||||
|
|
||||||
artifactRules = "build/distributions/*"
|
artifactRules = "build/distributions/*"
|
||||||
buildNumberPattern = "$VERSION.%build.counter%"
|
buildNumberPattern = "$DEV_VERSION-eap.%build.counter%"
|
||||||
|
|
||||||
params {
|
params {
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.2")
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", RELEASE_EAP)
|
||||||
password(
|
password(
|
||||||
"env.ORG_GRADLE_PROJECT_publishToken",
|
"env.ORG_GRADLE_PROJECT_publishToken",
|
||||||
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
||||||
label = "Password"
|
label = "Password"
|
||||||
)
|
)
|
||||||
param("env.ORG_GRADLE_PROJECT_publishUsername", "Aleksei.Plate")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
param("env.ORG_GRADLE_PROJECT_publishChannels", EAP)
|
param("env.ORG_GRADLE_PROJECT_publishChannels", EAP_CHANNEL)
|
||||||
password(
|
password(
|
||||||
"env.ORG_GRADLE_PROJECT_slackUrl",
|
"env.ORG_GRADLE_PROJECT_slackUrl",
|
||||||
"credentialsJSON:a8ab8150-e6f8-4eaf-987c-bcd65eac50b5",
|
"credentialsJSON:a8ab8150-e6f8-4eaf-987c-bcd65eac50b5",
|
||||||
@@ -38,12 +38,12 @@ object ReleaseEap : BuildType({
|
|||||||
vcs {
|
vcs {
|
||||||
root(DslContext.settingsRoot)
|
root(DslContext.settingsRoot)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
gradle {
|
gradle {
|
||||||
tasks = "clean publishPlugin slackEapNotification"
|
tasks = "clean publishPlugin"
|
||||||
buildFile = ""
|
buildFile = ""
|
||||||
enableStacktrace = true
|
enableStacktrace = true
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
@@ -53,9 +53,21 @@ object ReleaseEap : BuildType({
|
|||||||
features {
|
features {
|
||||||
vcsLabeling {
|
vcsLabeling {
|
||||||
vcsRootId = "${DslContext.settingsRoot.id}"
|
vcsRootId = "${DslContext.settingsRoot.id}"
|
||||||
labelingPattern = "%system.build.number%-EAP"
|
labelingPattern = "%system.build.number%"
|
||||||
successfulOnly = true
|
successfulOnly = true
|
||||||
branchFilter = ""
|
branchFilter = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.ARTIFACT_SIZE
|
||||||
|
threshold = 5
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.DIFF
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
45
.teamcity/_Self/buildTypes/Release_201.kt
vendored
@@ -1,45 +0,0 @@
|
|||||||
package _Self.buildTypes
|
|
||||||
|
|
||||||
import _Self.Constants.DEFAULT
|
|
||||||
import _Self.Constants.DEV
|
|
||||||
import _Self.Constants.EAP
|
|
||||||
import _Self.Constants.VERSION
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
|
||||||
|
|
||||||
object Release_201 : BuildType({
|
|
||||||
name = "Publish Release 2020.1"
|
|
||||||
description = "Build and publish IdeaVim plugin"
|
|
||||||
|
|
||||||
artifactRules = "build/distributions/*"
|
|
||||||
buildNumberPattern = "$VERSION-2020.1"
|
|
||||||
|
|
||||||
params {
|
|
||||||
param("env.ORG_GRADLE_PROJECT_ideaVersion", "2020.1")
|
|
||||||
password(
|
|
||||||
"env.ORG_GRADLE_PROJECT_publishToken",
|
|
||||||
"credentialsJSON:61a36031-4da1-4226-a876-b8148bf32bde",
|
|
||||||
label = "Password"
|
|
||||||
)
|
|
||||||
param("env.ORG_GRADLE_PROJECT_publishUsername", "Aleksei.Plate")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_version", "%build.number%")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
|
||||||
param("env.ORG_GRADLE_PROJECT_publishChannels", "$DEFAULT,$EAP,$DEV")
|
|
||||||
}
|
|
||||||
|
|
||||||
vcs {
|
|
||||||
root(_Self.vcsRoots.Branch_201)
|
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
|
||||||
}
|
|
||||||
|
|
||||||
steps {
|
|
||||||
gradle {
|
|
||||||
tasks = "clean publishPlugin"
|
|
||||||
buildFile = ""
|
|
||||||
enableStacktrace = true
|
|
||||||
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
@@ -3,6 +3,8 @@ package _Self.buildTypes
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
object TestsForIntelliJ20183 : BuildType({
|
object TestsForIntelliJ20183 : BuildType({
|
||||||
@@ -20,7 +22,7 @@ object TestsForIntelliJ20183 : BuildType({
|
|||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.Branch_183)
|
root(_Self.vcsRoots.Branch_183)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -41,4 +43,16 @@ object TestsForIntelliJ20183 : BuildType({
|
|||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@@ -5,6 +5,8 @@ package _Self.buildTypes
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
sealed class TestsForIntelliJ_181_branch(private val version: String) : BuildType({
|
sealed class TestsForIntelliJ_181_branch(private val version: String) : BuildType({
|
||||||
@@ -20,7 +22,7 @@ sealed class TestsForIntelliJ_181_branch(private val version: String) : BuildTyp
|
|||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.Branch_181)
|
root(_Self.vcsRoots.Branch_181)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -41,6 +43,18 @@ sealed class TestsForIntelliJ_181_branch(private val version: String) : BuildTyp
|
|||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
object TestsForIntelliJ20181 : TestsForIntelliJ_181_branch("2018.1")
|
object TestsForIntelliJ20181 : TestsForIntelliJ_181_branch("2018.1")
|
||||||
|
@@ -5,6 +5,8 @@ package _Self.buildTypes
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
sealed class TestsForIntelliJ_191_193_branch(private val version: String) : BuildType({
|
sealed class TestsForIntelliJ_191_193_branch(private val version: String) : BuildType({
|
||||||
@@ -21,7 +23,7 @@ sealed class TestsForIntelliJ_191_193_branch(private val version: String) : Buil
|
|||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.Branch_191_193)
|
root(_Self.vcsRoots.Branch_191_193)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -42,6 +44,18 @@ sealed class TestsForIntelliJ_191_193_branch(private val version: String) : Buil
|
|||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
object TestsForIntelliJ20191 : TestsForIntelliJ_191_193_branch("2019.1")
|
object TestsForIntelliJ20191 : TestsForIntelliJ_191_193_branch("2019.1")
|
||||||
|
@@ -5,6 +5,8 @@ package _Self.buildTypes
|
|||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
sealed class TestsForIntelliJ_201_branch(private val version: String) : BuildType({
|
sealed class TestsForIntelliJ_201_branch(private val version: String) : BuildType({
|
||||||
@@ -20,7 +22,7 @@ sealed class TestsForIntelliJ_201_branch(private val version: String) : BuildTyp
|
|||||||
vcs {
|
vcs {
|
||||||
root(_Self.vcsRoots.Branch_201)
|
root(_Self.vcsRoots.Branch_201)
|
||||||
|
|
||||||
checkoutMode = CheckoutMode.ON_SERVER
|
checkoutMode = CheckoutMode.AUTO
|
||||||
}
|
}
|
||||||
|
|
||||||
steps {
|
steps {
|
||||||
@@ -41,6 +43,18 @@ sealed class TestsForIntelliJ_201_branch(private val version: String) : BuildTyp
|
|||||||
requirements {
|
requirements {
|
||||||
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
object TestsForIntelliJ20201 : TestsForIntelliJ_201_branch("2020.1")
|
object TestsForIntelliJ20201 : TestsForIntelliJ_201_branch("2020.1")
|
||||||
|
60
.teamcity/_Self/buildTypes/TestsForIntelliJ_202.kt
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
@file:Suppress("ClassName")
|
||||||
|
|
||||||
|
package _Self.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.CheckoutMode
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.gradle
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.BuildFailureOnMetric
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.failureConditions.failOnMetricChange
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.triggers.vcs
|
||||||
|
|
||||||
|
sealed class TestsForIntelliJ_202_branch(private val version: String) : BuildType({
|
||||||
|
name = "Tests for IntelliJ $version"
|
||||||
|
|
||||||
|
params {
|
||||||
|
param("env.ORG_GRADLE_PROJECT_downloadIdeaSources", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_ideaVersion", "IC-$version")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_instrumentPluginCode", "false")
|
||||||
|
param("env.ORG_GRADLE_PROJECT_javaVersion", "1.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
vcs {
|
||||||
|
root(_Self.vcsRoots.Branch_202)
|
||||||
|
|
||||||
|
checkoutMode = CheckoutMode.AUTO
|
||||||
|
}
|
||||||
|
|
||||||
|
steps {
|
||||||
|
gradle {
|
||||||
|
tasks = "clean test"
|
||||||
|
buildFile = ""
|
||||||
|
enableStacktrace = true
|
||||||
|
param("org.jfrog.artifactory.selectedDeployableServer.defaultModuleVersionConfiguration", "GLOBAL")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
vcs {
|
||||||
|
branchFilter = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requirements {
|
||||||
|
noLessThanVer("teamcity.agent.jvm.version", "1.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
failureConditions {
|
||||||
|
failOnMetricChange {
|
||||||
|
metric = BuildFailureOnMetric.MetricType.TEST_COUNT
|
||||||
|
threshold = 20
|
||||||
|
units = BuildFailureOnMetric.MetricUnit.PERCENTS
|
||||||
|
comparison = BuildFailureOnMetric.MetricComparison.LESS
|
||||||
|
compareTo = build {
|
||||||
|
buildRule = lastSuccessful()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
object TestsForIntelliJ20202 : TestsForIntelliJ_202_branch("2020.2")
|
11
.teamcity/_Self/subprojects/GitHub.kt
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package _Self.subprojects
|
||||||
|
|
||||||
|
import _Self.buildTypes.GithubTests
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
||||||
|
|
||||||
|
object GitHub : Project({
|
||||||
|
name = "Pull Requests checks"
|
||||||
|
description = "Automatic checking of GitHub Pull Requests"
|
||||||
|
|
||||||
|
buildType(GithubTests)
|
||||||
|
})
|
2
.teamcity/_Self/subprojects/OldTests.kt
vendored
@@ -7,12 +7,14 @@ import _Self.buildTypes.TestsForIntelliJ20191
|
|||||||
import _Self.buildTypes.TestsForIntelliJ20192
|
import _Self.buildTypes.TestsForIntelliJ20192
|
||||||
import _Self.buildTypes.TestsForIntelliJ20193
|
import _Self.buildTypes.TestsForIntelliJ20193
|
||||||
import _Self.buildTypes.TestsForIntelliJ20201
|
import _Self.buildTypes.TestsForIntelliJ20201
|
||||||
|
import _Self.buildTypes.TestsForIntelliJ20202
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
||||||
|
|
||||||
object OldTests : Project({
|
object OldTests : Project({
|
||||||
name = "Old IdeaVim tests"
|
name = "Old IdeaVim tests"
|
||||||
description = "Tests for older versions of IJ"
|
description = "Tests for older versions of IJ"
|
||||||
|
|
||||||
|
buildType(TestsForIntelliJ20202)
|
||||||
buildType(TestsForIntelliJ20201)
|
buildType(TestsForIntelliJ20201)
|
||||||
buildType(TestsForIntelliJ20191)
|
buildType(TestsForIntelliJ20191)
|
||||||
buildType(TestsForIntelliJ20181)
|
buildType(TestsForIntelliJ20181)
|
||||||
|
2
.teamcity/_Self/subprojects/Releases.kt
vendored
@@ -3,7 +3,6 @@ package _Self.subprojects
|
|||||||
import _Self.buildTypes.Release
|
import _Self.buildTypes.Release
|
||||||
import _Self.buildTypes.ReleaseDev
|
import _Self.buildTypes.ReleaseDev
|
||||||
import _Self.buildTypes.ReleaseEap
|
import _Self.buildTypes.ReleaseEap
|
||||||
import _Self.buildTypes.Release_201
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
||||||
|
|
||||||
object Releases : Project({
|
object Releases : Project({
|
||||||
@@ -11,7 +10,6 @@ object Releases : Project({
|
|||||||
description = "Stable and EAP releases for IdeaVim"
|
description = "Stable and EAP releases for IdeaVim"
|
||||||
|
|
||||||
buildType(Release)
|
buildType(Release)
|
||||||
buildType(Release_201)
|
|
||||||
buildType(ReleaseEap)
|
buildType(ReleaseEap)
|
||||||
buildType(ReleaseDev)
|
buildType(ReleaseDev)
|
||||||
})
|
})
|
||||||
|
12
.teamcity/_Self/vcsRoots/Branch_202.kt
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@file:Suppress("ClassName")
|
||||||
|
|
||||||
|
package _Self.vcsRoots
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
|
object Branch_202 : GitVcsRoot({
|
||||||
|
name = "https://github.com/JetBrains/ideavim (branch 202)"
|
||||||
|
url = "https://github.com/JetBrains/ideavim.git"
|
||||||
|
branch = "202"
|
||||||
|
useMirrors = false
|
||||||
|
})
|
38
.teamcity/patches/buildTypes/Qodana.kts
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package patches.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.Qodana
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.buildSteps.qodana
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
|
||||||
|
|
||||||
|
/*
|
||||||
|
This patch script was generated by TeamCity on settings change in UI.
|
||||||
|
To apply the patch, change the buildType with id = 'Qodana'
|
||||||
|
accordingly, and delete the patch script.
|
||||||
|
*/
|
||||||
|
changeBuildType(RelativeId("Qodana")) {
|
||||||
|
expectSteps {
|
||||||
|
qodana {
|
||||||
|
name = "Qodana"
|
||||||
|
reportAsTestsEnable = "true"
|
||||||
|
failBuildOnErrors = ""
|
||||||
|
codeInspectionXmlConfig = "Custom"
|
||||||
|
codeInspectionCustomXmlConfigPath = ".idea/inspectionProfiles/Qodana.xml"
|
||||||
|
param("clonefinder-enable", "true")
|
||||||
|
param("clonefinder-languages", "Java")
|
||||||
|
param("clonefinder-languages-container", "Java Kotlin")
|
||||||
|
param("clonefinder-mode", "")
|
||||||
|
param("clonefinder-queried-project", "src")
|
||||||
|
param("clonefinder-reference-projects", "src")
|
||||||
|
param("namesAndTagsCustom", "repo.labs.intellij.net/static-analyser/qodana")
|
||||||
|
param("report-version", "")
|
||||||
|
param("yaml-configuration", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
update<Qodana>(0) {
|
||||||
|
clearConditions()
|
||||||
|
param("licenseaudit-enable", "true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
.teamcity/patches/buildTypes/Release.kts
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package patches.buildTypes
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
|
||||||
|
|
||||||
|
/*
|
||||||
|
This patch script was generated by TeamCity on settings change in UI.
|
||||||
|
To apply the patch, change the buildType with id = 'Release'
|
||||||
|
accordingly, and delete the patch script.
|
||||||
|
*/
|
||||||
|
changeBuildType(RelativeId("Release")) {
|
||||||
|
vcs {
|
||||||
|
remove(DslContext.settingsRoot.id!!)
|
||||||
|
add(RelativeId("Branch_Release"))
|
||||||
|
}
|
||||||
|
}
|
68
.teamcity/patches/projects/_Self.kts
vendored
@@ -1,68 +0,0 @@
|
|||||||
package patches.projects
|
|
||||||
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.Project
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ProjectFeature
|
|
||||||
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
|
|
||||||
|
|
||||||
/*
|
|
||||||
This patch script was generated by TeamCity on settings change in UI.
|
|
||||||
To apply the patch, change the root project
|
|
||||||
accordingly, and delete the patch script.
|
|
||||||
*/
|
|
||||||
changeProject(DslContext.projectId) {
|
|
||||||
features {
|
|
||||||
val feature1 = find<ProjectFeature> {
|
|
||||||
feature {
|
|
||||||
type = "CloudImage"
|
|
||||||
id = "PROJECT_EXT_768"
|
|
||||||
param("agent_pool_id", "41")
|
|
||||||
param("amazon-id", "ami-0d1a6a32faa92923e")
|
|
||||||
param("ebs-optimized", "false")
|
|
||||||
param("image-instances-limit", "")
|
|
||||||
param("image-name-prefix", "BuildAgentsIdeaVim")
|
|
||||||
param("instance-type", "c5d.xlarge")
|
|
||||||
param("key-pair-name", "teamcity-prod-pub")
|
|
||||||
param("profileId", "amazon-48")
|
|
||||||
param("security-group-ids", "sg-eda08696,sg-7332cf0f,")
|
|
||||||
param("source-id", "BuildAgentsIdeaVim")
|
|
||||||
param("spot-instance-price", "0.12")
|
|
||||||
param("subnet-id", "subnet-58839511")
|
|
||||||
param("use-spot-instances", "true")
|
|
||||||
param("user-tags", "project=idea-vim")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
feature1.apply {
|
|
||||||
param("spot-instance-price", "")
|
|
||||||
param("key-pair-name", "")
|
|
||||||
}
|
|
||||||
val feature2 = find<ProjectFeature> {
|
|
||||||
feature {
|
|
||||||
type = "CloudProfile"
|
|
||||||
id = "amazon-48"
|
|
||||||
param("agentPushPreset", "")
|
|
||||||
param("cloud-code", "amazon")
|
|
||||||
param("description", "")
|
|
||||||
param("enabled", "true")
|
|
||||||
param("max-running-instances", "10")
|
|
||||||
param("name", "Cloud Agents")
|
|
||||||
param("next-hour", "")
|
|
||||||
param("not-checked", "")
|
|
||||||
param("profileId", "amazon-48")
|
|
||||||
param("profileServerUrl", "")
|
|
||||||
param("region", "eu-west-1")
|
|
||||||
param("secure:access-id", "credentialsJSON:dbcdb2a2-de5f-4bc9-9421-292b19e83947")
|
|
||||||
param("secure:secret-key", "credentialsJSON:65a87fe7-0977-4af9-96f1-344f2b82d269")
|
|
||||||
param("system.cloud.profile_id", "amazon-48")
|
|
||||||
param("terminate-idle-time", "15")
|
|
||||||
param("total-work-time", "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
feature2.apply {
|
|
||||||
param("user-script", "")
|
|
||||||
param("spot-fleet-config", "")
|
|
||||||
param("terminate-after-build", "true")
|
|
||||||
param("name", "Cloud Agents - Single Build")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
18
.teamcity/patches/vcsRoots/Branch_Release.kts
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package patches.vcsRoots
|
||||||
|
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.*
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.ui.*
|
||||||
|
import jetbrains.buildServer.configs.kotlin.v2019_2.vcs.GitVcsRoot
|
||||||
|
|
||||||
|
/*
|
||||||
|
This patch script was generated by TeamCity on settings change in UI.
|
||||||
|
To apply the patch, create a vcsRoot with id = 'Branch_Release'
|
||||||
|
in the root project, and delete the patch script.
|
||||||
|
*/
|
||||||
|
create(DslContext.projectId, GitVcsRoot({
|
||||||
|
id("Branch_Release")
|
||||||
|
name = "https://github.com/JetBrains/ideavim (branch release)"
|
||||||
|
url = "https://github.com/JetBrains/ideavim.git"
|
||||||
|
branch = "release"
|
||||||
|
}))
|
||||||
|
|
38
AUTHORS.md
@@ -348,13 +348,45 @@ Contributors:
|
|||||||
[![icon][github]](https://github.com/daya0576)
|
[![icon][github]](https://github.com/daya0576)
|
||||||
|
|
||||||
大牙(Henry Zhu)
|
大牙(Henry Zhu)
|
||||||
|
* [![icon][mail]](mailto:mplacek@skilltech.pl)
|
||||||
|
[![icon][github]](https://github.com/MichalPlacek)
|
||||||
|
|
||||||
|
MichalPlacek
|
||||||
|
* [![icon][mail]](mailto:shrikantsharat.k@gmail.com)
|
||||||
|
[![icon][github]](https://github.com/sharat87)
|
||||||
|
|
||||||
|
Shrikant Sharat Kandula
|
||||||
|
* [![icon][mail]](mailto:michal.placek@yandex.com)
|
||||||
|
[![icon][github]](https://github.com/MichalPlacek)
|
||||||
|
|
||||||
|
Michal Placek
|
||||||
|
* [![icon][mail]](mailto:eugene.nizienko@jetbrains.com)
|
||||||
|
[![icon][github]](https://github.com/nizienko)
|
||||||
|
|
||||||
|
eugene nizienko
|
||||||
|
* [![icon][mail]](mailto:x@lipp.fi)
|
||||||
|
[![icon][github]](https://github.com/lippfi)
|
||||||
|
|
||||||
|
Filipp Vakhitov
|
||||||
|
* [![icon][mail]](mailto:yzeiri.1@osu.edu)
|
||||||
|
[![icon][github]](https://github.com/myzeiri)
|
||||||
|
|
||||||
|
Martin Yzeiri
|
||||||
|
* [![icon][mail]](mailto:jeyko1@gmail.com)
|
||||||
|
[![icon][github]](https://github.com/wrightwriter)
|
||||||
|
|
||||||
|
Petar Guglev
|
||||||
|
* [![icon][mail]](mailto:contact@chylex.com)
|
||||||
|
[![icon][github]](https://github.com/chylex)
|
||||||
|
|
||||||
|
chylex
|
||||||
|
|
||||||
If you are a contributor and your name is not listed here, feel free to
|
If you are a contributor and your name is not listed here, feel free to
|
||||||
contact the maintainers.
|
contact the maintainers.
|
||||||
|
|
||||||
<a href="https://icons8.com">Icons by Icons8</a>
|
<a href="https://icons8.com">Icons by Icons8</a>
|
||||||
|
|
||||||
[mail]: resources/icons/mail.png
|
[mail]: assets/icons/mail.png
|
||||||
[github]: resources/icons/github.png
|
[github]: assets/icons/github.png
|
||||||
|
|
||||||
[github-off]: resources/icons/github-off.png
|
[github-off]: assets/icons/github-off.png
|
||||||
|
194
CHANGES.md
@@ -4,17 +4,18 @@ The Changelog
|
|||||||
History of changes in IdeaVim for the IntelliJ platform.
|
History of changes in IdeaVim for the IntelliJ platform.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project DOES NOT adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
Before version 1.7.0:
|
||||||
Stable versions use X.Y format.
|
Stable versions use X.Y format.
|
||||||
EAP versions use X.Y.Z format.
|
EAP ([Early Access Program](https://jb.gg/ideavim-eap)) versions use X.Y.Z format.
|
||||||
|
|
||||||
|
|
||||||
Get an Early Access
|
Get an Early Access
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Would you like to try new features and fixes? Join the Early Access Program and
|
Would you like to try new features and fixes? Join the Early Access Program and
|
||||||
receive EAP builds as updates! Use the `EAP` option in the status bar or
|
receive EAP builds as updates! Use the `Early Access Program` option in the status bar or
|
||||||
add this URL to "Settings | Plugins | Manage Plugin Repositories":
|
add this URL to "Settings | Plugins | Manage Plugin Repositories":
|
||||||
`https://plugins.jetbrains.com/plugins/eap/ideavim`
|
`https://plugins.jetbrains.com/plugins/eap/ideavim`
|
||||||
|
|
||||||
@@ -24,8 +25,190 @@ usual beta standards.
|
|||||||
|
|
||||||
## To Be Released
|
## To Be Released
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Add register support to let command | [VIM-749](https://youtrack.jetbrains.com/issue/VIM-749)
|
||||||
|
* Add register support to let command | [VIM-1783](https://youtrack.jetbrains.com/issue/VIM-1783)
|
||||||
|
* Add `trackactionids`/`tai` option to track action ids
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2502](https://youtrack.jetbrains.com/issue/VIM-2502) Fix the shape of new carets
|
||||||
|
* [VIM-2499](https://youtrack.jetbrains.com/issue/VIM-2499) Fix mapping to esc
|
||||||
|
* [VIM-2500](https://youtrack.jetbrains.com/issue/VIM-2500) Fix esc for normal mode
|
||||||
|
|
||||||
|
## 1.9.0, 2021-12-10
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Make IdeaVim compatible with CodeWithMe | [VIM-2332](https://youtrack.jetbrains.com/issue/VIM-2332)
|
||||||
|
* expression register `<C-R>=` | [VIM-521](https://youtrack.jetbrains.com/issue/VIM-521)
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2442](https://youtrack.jetbrains.com/issue/VIM-2442) Fix `!` command
|
||||||
|
* [VIM-2255](https://youtrack.jetbrains.com/issue/VIM-2255) Fix reload icon on windows
|
||||||
|
* [VIM-2199](https://youtrack.jetbrains.com/issue/VIM-2199) Fix autocompletion for AppCode
|
||||||
|
* [VIM-2445](https://youtrack.jetbrains.com/issue/VIM-2445) Fix spaces in range
|
||||||
|
* [VIM-2450](https://youtrack.jetbrains.com/issue/VIM-2450) Fix set command
|
||||||
|
* [VIM-2451](https://youtrack.jetbrains.com/issue/VIM-2451) Fix comments
|
||||||
|
* [VIM-2452](https://youtrack.jetbrains.com/issue/VIM-2452) Fix augroup
|
||||||
|
* [VIM-2453](https://youtrack.jetbrains.com/issue/VIM-2453) Fix split command
|
||||||
|
* [VIM-2397](https://youtrack.jetbrains.com/issue/VIM-2397) Fix dollar motion as an operator
|
||||||
|
* [VIM-2432](https://youtrack.jetbrains.com/issue/VIM-2432) Fix ctrl-d and ctrl-u motions with scrolloff
|
||||||
|
* [VIM-2462](https://youtrack.jetbrains.com/issue/VIM-2462) Reset caret shape when disabling plugin
|
||||||
|
* [VIM-2449](https://youtrack.jetbrains.com/issue/VIM-2449) Fix `I` for one-line block selection
|
||||||
|
* [VIM-2213](https://youtrack.jetbrains.com/issue/VIM-2213) Close VCS change popup on esc
|
||||||
|
* [VIM-2435](https://youtrack.jetbrains.com/issue/VIM-2435) Close diff window on esc
|
||||||
|
* [VIM-2461](https://youtrack.jetbrains.com/issue/VIM-2461) Show action id before action execution
|
||||||
|
* [VIM-2026](https://youtrack.jetbrains.com/issue/VIM-2026) Keep global marks after restart
|
||||||
|
* [VIM-1691](https://youtrack.jetbrains.com/issue/VIM-1691) Fix default path for `!` command
|
||||||
|
* [VIM-2487](https://youtrack.jetbrains.com/issue/VIM-2487)
|
||||||
|
[VIM-2434](https://youtrack.jetbrains.com/issue/VIM-2434)
|
||||||
|
Fix IdeaVim in PyCharm notebooks
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [390](https://github.com/JetBrains/ideavim/pull/390) by [chylex](https://github.com/chylex): [VIM-2255] Missing reload icon in .ideavimrc on Windows
|
||||||
|
* [391](https://github.com/JetBrains/ideavim/pull/391) by [Matt Ellis](https://github.com/citizenmatt): fix(VIM-2432): handle scrolloff with <C-D> and <C-U>
|
||||||
|
* [401](https://github.com/JetBrains/ideavim/pull/401) by [Matt Ellis](https://github.com/citizenmatt): Reset caret shape when disabling plugin
|
||||||
|
* [407](https://github.com/JetBrains/ideavim/pull/407) by [eugene nizienko](https://github.com/nizienko): Video recording for ui tests
|
||||||
|
* [418](https://github.com/JetBrains/ideavim/pull/418) by [chylex](https://github.com/chylex): Fix compile errors in unit tests on Windows
|
||||||
|
|
||||||
|
## 1.8.0, 2021-10-27
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Support `matchit.vim` extension for Ruby and XML/HTML [VIM-539](https://youtrack.jetbrains.com/issue/VIM-539) | [matchit.vim](https://github.com/chrisbra/matchit)
|
||||||
|
* IDE-specific configuration [VIM-1573](https://youtrack.jetbrains.com/issue/VIM-1573)
|
||||||
|
* Call command [VIM-2416](https://youtrack.jetbrains.com/issue/VIM-2416)
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2417](https://youtrack.jetbrains.com/issue/VIM-2417) Fix bars in substitute command
|
||||||
|
* [VIM-2425](https://youtrack.jetbrains.com/issue/VIM-2425) Fix reload button
|
||||||
|
* [VIM-2422](https://youtrack.jetbrains.com/issue/VIM-2422) Fix freeze
|
||||||
|
* [VIM-2420](https://youtrack.jetbrains.com/issue/VIM-2420) Fix freeze
|
||||||
|
* [VIM-2359](https://youtrack.jetbrains.com/issue/VIM-2359) Fix selection with VimExchange
|
||||||
|
* [VIM-2426](https://youtrack.jetbrains.com/issue/VIM-2426) Fix marks in commands
|
||||||
|
* [VIM-2438](https://youtrack.jetbrains.com/issue/VIM-2438) Fix marks in commands
|
||||||
|
* [DISCUSSION-386](https://github.com/JetBrains/ideavim/discussions/386) Fixed command with no spaces before argument
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [337](https://github.com/JetBrains/ideavim/pull/337) by [Matt Ellis](https://github.com/citizenmatt): guicursor!
|
||||||
|
* [343](https://github.com/JetBrains/ideavim/pull/343) by [Martin Yzeiri](https://github.com/myzeiri): Emulate matchit.vim
|
||||||
|
* [387](https://github.com/JetBrains/ideavim/pull/387) by [Petar Guglev](https://github.com/wrightwriter): Update README.md link
|
||||||
|
|
||||||
|
## 1.7.2, 2021-09-30
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2405](https://youtrack.jetbrains.com/issue/VIM-2405) ExExceptions during `map <expr>` execution are now displayed in status bar
|
||||||
|
* [VIM-2406](https://youtrack.jetbrains.com/issue/VIM-2406) Fix go to line command
|
||||||
|
* [VIM-2408](https://youtrack.jetbrains.com/issue/VIM-2408) Fix vim script parser
|
||||||
|
* [VIM-2409](https://youtrack.jetbrains.com/issue/VIM-2409) Fix substitute command
|
||||||
|
* [VIM-2411](https://youtrack.jetbrains.com/issue/VIM-2411) Fix vim script parser
|
||||||
|
|
||||||
|
## 1.7.1, 2021-09-20
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2400](https://youtrack.jetbrains.com/issue/VIM-2400) Fix vim script parser
|
||||||
|
* [VIM-2401](https://youtrack.jetbrains.com/issue/VIM-2401) Exceptions occurred during execution of `map<expr>` are now shown in status bar
|
||||||
|
* [VIM-2404](https://youtrack.jetbrains.com/issue/VIM-2404) Fix multiple pastes from unnamed clipboard
|
||||||
|
|
||||||
|
## 1.7.0, 2021-09-16
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* New engine for Vim Script execution. Check out the [GitHub Discussion](https://jb.gg/vim-script-discussion).
|
||||||
|
* Mapping keys to expressions (map \<expr>). See `:h map-expression`.
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2368](https://youtrack.jetbrains.com/issue/VIM-2368) Do not remove selection on right click
|
||||||
|
* [VIM-2392](https://youtrack.jetbrains.com/issue/VIM-2392) Fix possible out of bounds exception
|
||||||
|
* [VIM-2387](https://youtrack.jetbrains.com/issue/VIM-2387) Fix coping with unnamed and ideaput
|
||||||
|
|
||||||
|
### Changes:
|
||||||
|
* New versioning scheme. Current version is `1.7.0` instead of `0.70`.
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [349](https://github.com/JetBrains/ideavim/pull/349) by [eugene nizienko](https://github.com/nizienko): Run UI test ci
|
||||||
|
|
||||||
|
## 0.69, 2021-07-20
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Support several buffer management commands [VIM-1062](https://youtrack.jetbrains.com/issue/VIM-1062), [VIM-2335](https://youtrack.jetbrains.com/issue/VIM-2335)
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2317](https://youtrack.jetbrains.com/issue/VIM-2317) Fix memory leak
|
||||||
|
* [VIM-1357](https://youtrack.jetbrains.com/issue/VIM-1357)
|
||||||
|
[VIM-1566](https://youtrack.jetbrains.com/issue/VIM-1566) Fix external filters
|
||||||
|
* [VIM-2336](https://youtrack.jetbrains.com/issue/VIM-2336) Fix repeat for the `T` movement
|
||||||
|
* [VIM-1192](https://youtrack.jetbrains.com/issue/VIM-1192) Fix dollar motion from single command
|
||||||
|
* [VIM-1672](https://youtrack.jetbrains.com/issue/VIM-1672) IdeaVim correctly populates clipboard history
|
||||||
|
* [VIM-2351](https://youtrack.jetbrains.com/issue/VIM-2351) Correctly select last character when selecting with mouse
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [332](https://github.com/JetBrains/ideavim/pull/332) by [Matt Ellis](https://github.com/citizenmatt): VIM-1357+VIM-1566: Use OS shell to run filter command
|
||||||
|
* [333](https://github.com/JetBrains/ideavim/pull/333) by [Michal Placek](https://github.com/MichalPlacek): VIM-1062
|
||||||
|
* [334](https://github.com/JetBrains/ideavim/pull/334) by [Michal Placek](https://github.com/MichalPlacek): vim-2335 Support for navigation to previous buffer with :b#
|
||||||
|
|
||||||
|
## 0.68, 2021-06-22
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Support `:global` and `:vglobal` commands [VIM-831](https://youtrack.jetbrains.com/issue/VIM-831), [VIM-832](https://youtrack.jetbrains.com/issue/VIM-832)
|
||||||
|
* Support `vim-indent-object` extension [VIM-1151](https://youtrack.jetbrains.com/issue/VIM-1151) | [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object)
|
||||||
|
* Support `:print` command
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2308](https://youtrack.jetbrains.com/issue/VIM-2308) Go to next tab doesn't move scrolling
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [261](https://github.com/JetBrains/ideavim/pull/261) by [Shrikant Sharat Kandula](https://github.com/sharat87): New extension: Indentation based text objects
|
||||||
|
* [308](https://github.com/JetBrains/ideavim/pull/308) by [Matt Ellis](https://github.com/citizenmatt): Fix unnecessary caret movement when switching tabs
|
||||||
|
|
||||||
|
## 0.67, 2021-05-20
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Support `sethandler` command to configure shortcuts conflicts via `~/.ideavimrc` file. See [docs](https://jb.gg/vim-sethandler).
|
||||||
|
* Support `vim-paragraph-motion` extension [VIM-2290](https://youtrack.jetbrains.com/issue/VIM-2290) | [vim-paragraph-motion](https://github.com/dbakker/vim-paragraph-motion)
|
||||||
|
* Add "Reset Handlers" button for "Conflicting Shortcuts" setting table
|
||||||
|
|
||||||
|
### Changes:
|
||||||
|
* Rename "Vim Emulation" in settings to "Vim"
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2230](https://youtrack.jetbrains.com/issue/VIM-2230) Tweak caret position with inline rename options inlay
|
||||||
|
* [VIM-2177](https://youtrack.jetbrains.com/issue/VIM-2177) Fix scrolling issues near bottom of file
|
||||||
|
* [VIM-2276](https://youtrack.jetbrains.com/issue/VIM-2276) `:ls` returns correct path for files on Microsoft Windows.
|
||||||
|
* [VIM-1953](https://youtrack.jetbrains.com/issue/VIM-1953) Execute live testing for `:w` command
|
||||||
|
* [VIM-2284](https://youtrack.jetbrains.com/issue/VIM-2284) Values are not duplicated in set command
|
||||||
|
* [VIM-2289](https://youtrack.jetbrains.com/issue/VIM-2289) Fix `<End>` command behaviour
|
||||||
|
* [VIM-1476](https://youtrack.jetbrains.com/issue/VIM-1476) Last inserted text is stored in `.` register
|
||||||
|
* [VIM-2295](https://youtrack.jetbrains.com/issue/VIM-2295) Fix `<S-Space>` in insert mode with an existing mapping
|
||||||
|
* [VIM-1401](https://youtrack.jetbrains.com/issue/VIM-1401) IdeaVim triggers readonly handler
|
||||||
|
* [VIM-1856](https://youtrack.jetbrains.com/issue/VIM-1856) Support defining shortcuts in .ideavimrc
|
||||||
|
* [VIM-1523](https://youtrack.jetbrains.com/issue/VIM-1523) Allow different shortcut handlers in different modes
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [280](https://github.com/JetBrains/ideavim/pull/280) by [Matt Ellis](https://github.com/citizenmatt): Caret position and view scrolling fixes
|
||||||
|
* [289](https://github.com/JetBrains/ideavim/pull/289) by [MichalPlacek](https://github.com/MichalPlacek): VIM-2276 ls returns "absolute path" for files on Microsoft Windows.
|
||||||
|
* [295](https://github.com/JetBrains/ideavim/pull/295) by [MichalPlacek](https://github.com/MichalPlacek): VIM-1476
|
||||||
|
|
||||||
|
## 0.66, 2021-04-09
|
||||||
|
|
||||||
|
Not a lot of changes for this release. Focused on internal improvements.
|
||||||
|
|
||||||
|
### Features:
|
||||||
|
* Support `startofline` option
|
||||||
|
|
||||||
|
### Fixes:
|
||||||
|
* [VIM-2238](https://youtrack.jetbrains.com/issue/VIM-2238) Fix `M` command for small files
|
||||||
|
|
||||||
|
### Merged PRs:
|
||||||
|
* [275](https://github.com/JetBrains/ideavim/pull/275) by [Matt Ellis](https://github.com/citizenmatt): Fix edge cases for H, L and M and introduce 'startofline' option
|
||||||
|
* [276](https://github.com/JetBrains/ideavim/pull/276) by [Matt Ellis](https://github.com/citizenmatt): More refactoring of SearchGroup
|
||||||
|
|
||||||
|
## 0.65, 2021-02-17
|
||||||
|
|
||||||
### Features:
|
### Features:
|
||||||
* Support `NERDTree` extension [VIM-1042](https://youtrack.jetbrains.com/issue/VIM-1042) | [NERDTree](https://github.com/preservim/nerdtree)
|
* Support `NERDTree` extension [VIM-1042](https://youtrack.jetbrains.com/issue/VIM-1042) | [NERDTree](https://github.com/preservim/nerdtree)
|
||||||
|
|
||||||
|
* <details>
|
||||||
|
<summary><strong>Click to see details</strong></summary>
|
||||||
|
<img src="assets/changes/0.65/nerdtree.gif" alt="NERDTree example"/>
|
||||||
|
</details>
|
||||||
* Support `maxmapdepth` option to define the maximum depth of mappings
|
* Support `maxmapdepth` option to define the maximum depth of mappings
|
||||||
|
|
||||||
### Fixes:
|
### Fixes:
|
||||||
@@ -36,6 +219,7 @@ usual beta standards.
|
|||||||
* [VIM-2218](https://youtrack.jetbrains.com/issue/VIM-2218) Fix some shortcuts for 2021.+
|
* [VIM-2218](https://youtrack.jetbrains.com/issue/VIM-2218) Fix some shortcuts for 2021.+
|
||||||
* [VIM-2217](https://youtrack.jetbrains.com/issue/VIM-2217) Fix adding new line at the end of the file for the AppCode
|
* [VIM-2217](https://youtrack.jetbrains.com/issue/VIM-2217) Fix adding new line at the end of the file for the AppCode
|
||||||
* [VIM-2220](https://youtrack.jetbrains.com/issue/VIM-2220) Do not try to get a commandState for null editor
|
* [VIM-2220](https://youtrack.jetbrains.com/issue/VIM-2220) Do not try to get a commandState for null editor
|
||||||
|
* [VIM-2153](https://youtrack.jetbrains.com/issue/VIM-2153) Fix storing special characters after IDE closing
|
||||||
|
|
||||||
### Merged PRs:
|
### Merged PRs:
|
||||||
* [269](https://github.com/JetBrains/ideavim/pull/269) by [大牙(Henry Zhu)](https://github.com/daya0576): fix invalid link of submodule docs
|
* [269](https://github.com/JetBrains/ideavim/pull/269) by [大牙(Henry Zhu)](https://github.com/daya0576): fix invalid link of submodule docs
|
||||||
@@ -156,7 +340,7 @@ Use `set ideavimsupport=` to disable IdeaVim in dialog editors.
|
|||||||
|
|
||||||
* <details>
|
* <details>
|
||||||
<summary><strong>Click to see details</strong></summary>
|
<summary><strong>Click to see details</strong></summary>
|
||||||
<img src="resources/changes/0.59/highlight_yank.gif" alt="highlight yank"/>
|
<img src="assets/changes/0.59/highlight_yank.gif" alt="highlight yank"/>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
* [VIM-2068](https://youtrack.jetbrains.com/issue/VIM-2068) `:tabclose` command
|
* [VIM-2068](https://youtrack.jetbrains.com/issue/VIM-2068) `:tabclose` command
|
||||||
@@ -181,7 +365,7 @@ Use `set ideavimsupport=` to disable IdeaVim in dialog editors.
|
|||||||
|
|
||||||
* <details>
|
* <details>
|
||||||
<summary><strong>Click to see details</strong></summary>
|
<summary><strong>Click to see details</strong></summary>
|
||||||
<img src="resources/changes/0.58/reload_ideavimrc.png" alt="IdeaVimRc reload"/>
|
<img src="assets/changes/0.58/reload_ideavimrc.png" alt="IdeaVimRc reload"/>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
* Add `:buffer` command.
|
* Add `:buffer` command.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[![TeamCity Build][teamcity-build-status-svg]][teamcity-build-status]
|
[![TeamCity Build][teamcity-build-status-svg]][teamcity-build-status]
|
||||||
|
|
||||||
IdeaVim is an open source project created by 60+ contributors. Would you like to make it even better? That’s wonderful!
|
IdeaVim is an open source project created by 80+ contributors. Would you like to make it even better? That’s wonderful!
|
||||||
|
|
||||||
This page is created to help you start contributing. And who knows, maybe in a few days this project will be brighter than ever!
|
This page is created to help you start contributing. And who knows, maybe in a few days this project will be brighter than ever!
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ OK, ready to do some coding?
|
|||||||
Yoo hoo! You’re all set to begin contributing.
|
Yoo hoo! You’re all set to begin contributing.
|
||||||
We've prepared some useful configurations for you:
|
We've prepared some useful configurations for you:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
And here are useful gradle commands:
|
And here are useful gradle commands:
|
||||||
|
|
||||||
@@ -61,7 +61,9 @@ If you are looking for:
|
|||||||
|
|
||||||
- Ex commands (`:set`, `:s`, `:nohlsearch`):
|
- Ex commands (`:set`, `:s`, `:nohlsearch`):
|
||||||
- Any particular ex command: package `com.maddyhome.idea.vim.ex.handler`.
|
- Any particular ex command: package `com.maddyhome.idea.vim.ex.handler`.
|
||||||
- Ex command executor: `CommandHandler`.
|
- Vim script grammar: `Vimscript.g4`.
|
||||||
|
- Vim script parsing: package `com.maddyhome.idea.vim.vimscript.parser`.
|
||||||
|
- Vim script executor: `Executor`.
|
||||||
|
|
||||||
- Extensions:
|
- Extensions:
|
||||||
- Extensions handler: `VimExtensionHandler`.
|
- Extensions handler: `VimExtensionHandler`.
|
||||||
@@ -136,7 +138,7 @@ This is just terrible. [You know what to do](https://github.com/JetBrains/ideavi
|
|||||||
* [Continuous integration builds](https://teamcity.jetbrains.com/project.html?projectId=IdeaVim&guest=1)
|
* [Continuous integration builds](https://teamcity.jetbrains.com/project.html?projectId=IdeaVim&guest=1)
|
||||||
* [Bug tracker](https://youtrack.jetbrains.com/issues/VIM)
|
* [Bug tracker](https://youtrack.jetbrains.com/issues/VIM)
|
||||||
* [Chat on gitter](https://gitter.im/JetBrains/ideavim)
|
* [Chat on gitter](https://gitter.im/JetBrains/ideavim)
|
||||||
* [Unofficial discord server](https://jb.gg/bi6zp7)
|
* [IdeaVim Channel](https://jb.gg/bi6zp7) on [JetBrains Server](https://discord.gg/jetbrains)
|
||||||
* [Plugin homepage](https://plugins.jetbrains.com/plugin/164-ideavim)
|
* [Plugin homepage](https://plugins.jetbrains.com/plugin/164-ideavim)
|
||||||
* [Changelog](CHANGES.md)
|
* [Changelog](CHANGES.md)
|
||||||
* [Contributors listing](AUTHORS.md)
|
* [Contributors listing](AUTHORS.md)
|
||||||
|
116
README.md
@@ -1,4 +1,4 @@
|
|||||||
<img src="resources/META-INF/pluginIcon.svg" width="80" height="80" alt="icon" align="left"/>
|
<img src="src/main/resources/META-INF/pluginIcon.svg" width="80" height="80" alt="icon" align="left"/>
|
||||||
|
|
||||||
IdeaVim
|
IdeaVim
|
||||||
===
|
===
|
||||||
@@ -17,7 +17,7 @@ IdeaVim is a Vim emulation plugin for IntelliJ Platform-based IDEs.
|
|||||||
* [Bug tracker](https://youtrack.jetbrains.com/issues/VIM)
|
* [Bug tracker](https://youtrack.jetbrains.com/issues/VIM)
|
||||||
* [@IdeaVim](https://twitter.com/ideavim) on Twitter
|
* [@IdeaVim](https://twitter.com/ideavim) on Twitter
|
||||||
* [Chat on gitter](https://gitter.im/JetBrains/ideavim)
|
* [Chat on gitter](https://gitter.im/JetBrains/ideavim)
|
||||||
* [Unofficial discord server](https://jb.gg/bi6zp7)
|
* [IdeaVim Channel](https://jb.gg/bi6zp7) on [JetBrains Server](https://discord.gg/jetbrains)
|
||||||
|
|
||||||
##### Resources:
|
##### Resources:
|
||||||
|
|
||||||
@@ -36,13 +36,13 @@ Setup
|
|||||||
- IdeaVim can be installed via `Settings | Plugins`.
|
- IdeaVim can be installed via `Settings | Plugins`.
|
||||||
See the [detailed instructions](https://www.jetbrains.com/help/idea/managing-plugins.html#).
|
See the [detailed instructions](https://www.jetbrains.com/help/idea/managing-plugins.html#).
|
||||||
|
|
||||||
- Use `Tools | Vim Emulator` to enable or disable emulation.
|
- Use `Tools | Vim Emulator` in the menu to enable or disable emulation.
|
||||||
|
|
||||||
- Use the `~/.ideavimrc` file as an analog of `~/.vimrc` ([learn more](#Files)). The XDG standard is supported, as well.
|
- Use the `~/.ideavimrc` file as an analog of `~/.vimrc` ([learn more](#Files)). The XDG standard is supported, as well.
|
||||||
|
|
||||||
- Shortcut conflicts can be resolved by using:
|
- Shortcut conflicts can be resolved by using:
|
||||||
- On Linux & Windows: `File | Settings | Editor | Vim Emulation` & `File | Settings | Keymap`,
|
- On Linux & Windows: `File | Settings | Editor | Vim` & `File | Settings | Keymap`,
|
||||||
- On macOS: `Preferences | Editor | Vim Emulation` & `Preferences | Keymap`,
|
- On macOS: `Preferences | Editor | Vim` & `Preferences | Keymap`,
|
||||||
- Regular Vim mappings in the `~/.ideavimrc` file.
|
- Regular Vim mappings in the `~/.ideavimrc` file.
|
||||||
|
|
||||||
Get Early Access
|
Get Early Access
|
||||||
@@ -51,15 +51,17 @@ Get Early Access
|
|||||||
Would you like to try new features and fixes? Join the Early Access Program and
|
Would you like to try new features and fixes? Join the Early Access Program and
|
||||||
receive EAP builds as updates!
|
receive EAP builds as updates!
|
||||||
|
|
||||||
1. Click the IdeaVim icon <img src="resources/META-INF/pluginIcon_noBorders.svg" width="16" height="16" alt="icon"/>
|
1. Click the IdeaVim icon <img src="src/main/resources/META-INF/pluginIcon_noBorders.svg" width="16" height="16" alt="icon"/>
|
||||||
in the status bar | `EAP` | `Get Early Access...`
|
in the status bar | `Early Access Program` | `Subscibe to EAP`
|
||||||
|
|
||||||
|
|
||||||
Or subscribe to EAP updates manually:
|
Or subscribe to EAP updates manually:
|
||||||
|
|
||||||
1. Open `Settings | Plugins`
|
1. Open `Settings | Plugins`
|
||||||
2. Click the gear icon :gear:, select `Manage Plugin Repositories`, and add the following url:
|
2. Click the gear icon :gear:, select `Manage Plugin Repositories`, and add the following url:
|
||||||
`https://plugins.jetbrains.com/plugins/eap/ideavim`
|
```
|
||||||
|
https://plugins.jetbrains.com/plugins/eap/ideavim
|
||||||
|
```
|
||||||
|
|
||||||
See [the changelog](CHANGES.md) for the list of unreleased features.
|
See [the changelog](CHANGES.md) for the list of unreleased features.
|
||||||
|
|
||||||
@@ -89,6 +91,7 @@ Here are some examples of supported vim features and commands:
|
|||||||
[Emulated Vim plugins](https://github.com/JetBrains/ideavim/wiki/Emulated-plugins):
|
[Emulated Vim plugins](https://github.com/JetBrains/ideavim/wiki/Emulated-plugins):
|
||||||
|
|
||||||
* vim-easymotion
|
* vim-easymotion
|
||||||
|
* NERDTree
|
||||||
* vim-surround
|
* vim-surround
|
||||||
* vim-multiple-cursors
|
* vim-multiple-cursors
|
||||||
* vim-commentary
|
* vim-commentary
|
||||||
@@ -97,12 +100,16 @@ Here are some examples of supported vim features and commands:
|
|||||||
* ReplaceWithRegister
|
* ReplaceWithRegister
|
||||||
* vim-exchange
|
* vim-exchange
|
||||||
* vim-highlightedyank
|
* vim-highlightedyank
|
||||||
|
* vim-paragraph-motion
|
||||||
|
* vim-indent-object
|
||||||
|
* match.it
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
* [The list of all supported commands](src/com/maddyhome/idea/vim/package-info.java)
|
* [The list of all supported commands](src/main/java/com/maddyhome/idea/vim/package-info.java)
|
||||||
* [Top feature requests and bugs](https://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+sort+by%3A+votes)
|
* [Top feature requests and bugs](https://youtrack.jetbrains.com/issues/VIM?q=%23Unresolved+sort+by%3A+votes)
|
||||||
|
* [Vimscript support roadmap](vimscript-info/VIMSCRIPT_ROADMAP.md)
|
||||||
|
* [List of supported in-build functions](vimscript-info/FUNCTIONS_INFO.MD)
|
||||||
|
|
||||||
Files
|
Files
|
||||||
-----
|
-----
|
||||||
@@ -169,7 +176,7 @@ Here is also a list of the suggested options from [defaults.vim](https://github.
|
|||||||
" text scroll if you mouse-click near the start or end of the window.
|
" text scroll if you mouse-click near the start or end of the window.
|
||||||
set scrolloff=5
|
set scrolloff=5
|
||||||
|
|
||||||
" Do incremental searching
|
" Do incremental searching.
|
||||||
set incsearch
|
set incsearch
|
||||||
|
|
||||||
" Don't use Ex mode, use Q for formatting.
|
" Don't use Ex mode, use Q for formatting.
|
||||||
@@ -182,10 +189,6 @@ You can read your `~/.vimrc` file from `~/.ideavimrc` with this command:
|
|||||||
|
|
||||||
source ~/.vimrc
|
source ~/.vimrc
|
||||||
|
|
||||||
> :warning: Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
|
|
||||||
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
|
|
||||||
of VimL files.
|
|
||||||
|
|
||||||
Also note that if you have overridden the `user.home` JVM option, this
|
Also note that if you have overridden the `user.home` JVM option, this
|
||||||
will affect where IdeaVim looks for your `.ideavimrc` file. For example, if you
|
will affect where IdeaVim looks for your `.ideavimrc` file. For example, if you
|
||||||
have `-Duser.home=/my/alternate/home` then IdeaVim will source
|
have `-Duser.home=/my/alternate/home` then IdeaVim will source
|
||||||
@@ -206,25 +209,30 @@ Executing IDE Actions
|
|||||||
IdeaVim adds various commands for listing and executing arbitrary IDE actions as
|
IdeaVim adds various commands for listing and executing arbitrary IDE actions as
|
||||||
Ex commands or via `:map` command mappings:
|
Ex commands or via `:map` command mappings:
|
||||||
|
|
||||||
**Executing actions:**
|
### Executing actions:
|
||||||
* `:action {action_id}`
|
* `:action {action_id}`
|
||||||
* Execute an action by id. Works from Ex command line.
|
* Execute an action by `{action_id}`. Works from Ex command line.
|
||||||
* `<Action>(*action_id*)`
|
* `<Action>({action_id})`
|
||||||
* For the mappings you can use a special `<Action>` keyword. Don't forget the parentheses.
|
* For the mappings you can use a special `<Action>` keyword. Don't forget the parentheses.
|
||||||
|
* E.g. `map gh <Action>(ShowErrorDescription)` <- execute hover on `gh`.
|
||||||
|
* :warning: Mappings to `<Action>` don't work with `noremap`.
|
||||||
|
If you know the case when it's needed, please [let us know](https://github.com/JetBrains/ideavim#contact-maintainers).
|
||||||
|
|
||||||
**Finding actions:**
|
### Finding action ids:
|
||||||
* `:actionlist [pattern]`
|
|
||||||
* Find IDE actions by id or keymap pattern (E.g. `:actionlist extract`, `:actionlist <C-D`)
|
|
||||||
|
|
||||||
* In addition to `:actionlist` command, IdeaVim provides `IdeaVim: track action Ids` option to
|
* IJ provides `IdeaVim: track action Ids` command to show the id of the executed actions.
|
||||||
extract the ids of executed command. This option can be found in "Search everywhere" (double `shift`).
|
This command can be found in "Search everywhere" (double `shift`).
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><strong>"Track action Ids" Details</strong> (click to see)</summary>
|
<summary><strong>"Track action Ids" Details</strong> (click to see)</summary>
|
||||||
<img src="resources/readme/track_action_id.gif" alt="track action ids"/>
|
<img src="assets/readme/track_action_id.gif" alt="track action ids"/>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
* `:actionlist [pattern]`
|
||||||
|
* Find IDE actions by id or keymap pattern (E.g. `:actionlist extract`, `:actionlist <C-D`)
|
||||||
|
|
||||||
|
##### Examples:
|
||||||
|
|
||||||
```vim
|
```vim
|
||||||
" Map \r to the Reformat Code action
|
" Map \r to the Reformat Code action
|
||||||
@@ -237,6 +245,60 @@ Examples:
|
|||||||
:map \b <Action>(ToggleLineBreakpoint)
|
:map \b <Action>(ToggleLineBreakpoint)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### Some popular actions:
|
||||||
|
|
||||||
|
```
|
||||||
|
QuickJavaDoc - Quick Documentation (not only for java, all languages)
|
||||||
|
ShowErrorDescription - Show description of the error under the caret (cursor hovering)
|
||||||
|
QuickImplementations - Quick Definition
|
||||||
|
```
|
||||||
|
|
||||||
|
Vim Script
|
||||||
|
------------
|
||||||
|
|
||||||
|
IdeaVim can execute custom scripts that are written with Vim Script.
|
||||||
|
At the moment we support all language features, but not all of the built-in functions and options are supported.
|
||||||
|
|
||||||
|
Additionally, you may be interested in the
|
||||||
|
[Vim Script Discussion](https://github.com/JetBrains/ideavim/discussions/357) or
|
||||||
|
[Vim Script Roadmap](https://github.com/JetBrains/ideavim/blob/master/vimscript-info/VIMSCRIPT_ROADMAP.md).
|
||||||
|
|
||||||
|
|
||||||
|
### IDE specific options
|
||||||
|
|
||||||
|
You can evaluate the `has('ide')` function call and get `1` if it was called with IdeaVim or `0` if the function was called from Vim/NeoVim.
|
||||||
|
The option `&ide` contains the name and edition of your IDE, for example, "IntelliJ IDEA Ultimate Edition".
|
||||||
|
To see its value for the current IDE you are using, execute the `:echo &ide` command.
|
||||||
|
To write an IDE-specific configuration, use Vim's regexp match operators `=~?` (case-insensitive) / `=~#` (case-sensitive)
|
||||||
|
|
||||||
|
**Example config:**
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" options and mappings that are supported by both Vim and IdeaVim
|
||||||
|
set nu
|
||||||
|
set relativenumber
|
||||||
|
|
||||||
|
if has('ide')
|
||||||
|
" mappings and options that exist only in IdeaVim
|
||||||
|
map <leader>f <Action>(GotoFile)
|
||||||
|
map <leader>g <Action>(FindInPath)
|
||||||
|
map <leader>b <Action>(Switcher)
|
||||||
|
|
||||||
|
if &ide =~? 'intellij idea'
|
||||||
|
if &ide =~? 'community'
|
||||||
|
" some mappings and options for IntelliJ IDEA Community Edition
|
||||||
|
elseif &ide =~? 'ultimate'
|
||||||
|
" some mappings and options for IntelliJ IDEA Ultimate Edition
|
||||||
|
endif
|
||||||
|
elseif &ide =~? 'pycharm'
|
||||||
|
" PyCharm specific mappings and options
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" some mappings for Vim/Neovim
|
||||||
|
nnoremap <leader>f <cmd>Telescope find_files<cr>
|
||||||
|
endif
|
||||||
|
```
|
||||||
|
|
||||||
:gem: Contributing
|
:gem: Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@@ -260,10 +322,6 @@ IdeaVim tips and tricks
|
|||||||
- Check out more [ex commands](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
|
- Check out more [ex commands](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
|
||||||
|
|
||||||
- Use your vim settings with IdeaVim. Put `source ~/.vimrc` in `~/.ideavimrc`.
|
- Use your vim settings with IdeaVim. Put `source ~/.vimrc` in `~/.ideavimrc`.
|
||||||
> :warning: Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
|
|
||||||
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
|
|
||||||
of VimL files.
|
|
||||||
|
|
||||||
- Control the status bar icon via the [`ideastatusicon` option](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
|
- Control the status bar icon via the [`ideastatusicon` option](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
|
||||||
- Not familiar with the default behaviour during a refactoring? See the [`idearefactormode` option](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
|
- Not familiar with the default behaviour during a refactoring? See the [`idearefactormode` option](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 194 KiB |
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
BIN
assets/changes/0.65/nerdtree.gif
Normal file
After Width: | Height: | Size: 32 MiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 638 B After Width: | Height: | Size: 638 B |
Before Width: | Height: | Size: 364 B After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 2.1 MiB |
181
build.gradle
@@ -1,181 +0,0 @@
|
|||||||
import dev.feedforward.markdownto.DownParser
|
|
||||||
|
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
maven { url 'https://jitpack.io' }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
|
||||||
classpath "com.github.AlexPl292:mark-down-to-slack:1.1.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id 'org.jetbrains.intellij' version '0.6.5'
|
|
||||||
id 'io.gitlab.arturbosch.detekt' version '1.15.0'
|
|
||||||
id "org.jetbrains.changelog" version "1.0.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
|
||||||
apply plugin: 'kotlin'
|
|
||||||
|
|
||||||
sourceCompatibility = javaVersion
|
|
||||||
targetCompatibility = javaVersion
|
|
||||||
|
|
||||||
tasks.withType(JavaCompile) { options.encoding = 'UTF-8' }
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
java.srcDir 'src'
|
|
||||||
resources.srcDir 'resources'
|
|
||||||
}
|
|
||||||
test {
|
|
||||||
java.srcDir 'test'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intellij {
|
|
||||||
version ideaVersion
|
|
||||||
pluginName 'IdeaVim'
|
|
||||||
updateSinceUntilBuild false
|
|
||||||
downloadSources Boolean.valueOf(downloadIdeaSources)
|
|
||||||
instrumentCode Boolean.valueOf(instrumentPluginCode)
|
|
||||||
intellijRepo = "https://www.jetbrains.com/intellij-repository"
|
|
||||||
plugins = ['java']
|
|
||||||
|
|
||||||
downloadRobotServerPlugin.version = "0.10.0"
|
|
||||||
|
|
||||||
publishPlugin {
|
|
||||||
channels publishChannels.split(',')
|
|
||||||
username publishUsername
|
|
||||||
token publishToken
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runIdeForUiTests {
|
|
||||||
systemProperty "robot-server.port", "8082"
|
|
||||||
}
|
|
||||||
|
|
||||||
runPluginVerifier {
|
|
||||||
ideVersions = ["IC-2020.2.3", "IC-2020.3.2"]
|
|
||||||
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
|
|
||||||
teamCityOutputFormat = true
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
|
||||||
maven { url = "https://jetbrains.bintray.com/intellij-third-party-dependencies" }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
|
|
||||||
compileOnly "org.jetbrains:annotations:20.1.0"
|
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.ensarsarajcic.neovim.java/neovim-api
|
|
||||||
testImplementation("com.ensarsarajcic.neovim.java:neovim-api:0.2.0")
|
|
||||||
testImplementation 'com.ensarsarajcic.neovim.java:core-rpc:0.2.0'
|
|
||||||
|
|
||||||
testImplementation("com.intellij.remoterobot:remote-robot:0.10.3")
|
|
||||||
testImplementation("com.intellij.remoterobot:remote-fixtures:1.1.18")
|
|
||||||
}
|
|
||||||
|
|
||||||
compileKotlin {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = javaVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileTestKotlin {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = javaVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
detekt {
|
|
||||||
config = files("${rootProject.projectDir}/.detekt/config.yaml")
|
|
||||||
baseline = file("${rootProject.projectDir}/.detekt/baseline.xml")
|
|
||||||
input = files("src")
|
|
||||||
|
|
||||||
buildUponDefaultConfig = true
|
|
||||||
|
|
||||||
reports {
|
|
||||||
html.enabled = false
|
|
||||||
xml.enabled = false
|
|
||||||
txt.enabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.detekt.jvmTarget = javaVersion
|
|
||||||
|
|
||||||
task testWithNeovim(type: Test) {
|
|
||||||
group = "verification"
|
|
||||||
systemProperty "ideavim.nvim.test", 'true'
|
|
||||||
exclude '/ui/**'
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
exclude '**/propertybased/**'
|
|
||||||
exclude '/ui/**'
|
|
||||||
}
|
|
||||||
|
|
||||||
task testPropertyBased(type: Test) {
|
|
||||||
group = "verification"
|
|
||||||
include '**/propertybased/**'
|
|
||||||
}
|
|
||||||
|
|
||||||
task testUi(type: Test) {
|
|
||||||
group = "verification"
|
|
||||||
include '/ui/**'
|
|
||||||
}
|
|
||||||
|
|
||||||
changelog {
|
|
||||||
groups = ["Features:", "Changes:", "Deprecations:", "Fixes:", "Merged PRs:"]
|
|
||||||
itemPrefix = "*"
|
|
||||||
path = "${project.projectDir}/CHANGES.md"
|
|
||||||
unreleasedTerm = "To Be Released"
|
|
||||||
headerParserRegex = /0\.\d{2}(.\d+)?/
|
|
||||||
// header = { "${project.version}" }
|
|
||||||
// version = "0.60"
|
|
||||||
}
|
|
||||||
|
|
||||||
task getUnreleasedChangelog() {
|
|
||||||
group = "changelog"
|
|
||||||
doLast {
|
|
||||||
def log = changelog.getUnreleased().toHTML()
|
|
||||||
println log
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register("slackEapNotification") {
|
|
||||||
doLast {
|
|
||||||
if (!slackUrl) return
|
|
||||||
def post = new URL(slackUrl).openConnection()
|
|
||||||
def changeLog = changelog.getUnreleased().toText()
|
|
||||||
def slackDown = new DownParser(changeLog, true).toSlack().toString()
|
|
||||||
def message = """
|
|
||||||
{
|
|
||||||
"text": "New version of IdeaVim",
|
|
||||||
"blocks": [
|
|
||||||
{
|
|
||||||
"type": "section",
|
|
||||||
"text": {
|
|
||||||
"type": "mrkdwn",
|
|
||||||
"text": "IdeaVim EAP $version has been released\\n$slackDown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
post.setRequestMethod("POST")
|
|
||||||
post.setDoOutput(true)
|
|
||||||
post.setRequestProperty("Content-Type", "application/json")
|
|
||||||
post.getOutputStream().write(message.getBytes("UTF-8"))
|
|
||||||
def postRC = post.getResponseCode()
|
|
||||||
println(postRC)
|
|
||||||
if (postRC == 200) {
|
|
||||||
println(post.getInputStream().getText())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
536
build.gradle.kts
Normal file
@@ -0,0 +1,536 @@
|
|||||||
|
|
||||||
|
import dev.feedforward.markdownto.DownParser
|
||||||
|
import org.intellij.markdown.ast.getTextInNode
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven { url = uri("https://jitpack.io") }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.10")
|
||||||
|
classpath("com.github.AlexPl292:mark-down-to-slack:1.1.2")
|
||||||
|
classpath("org.eclipse.jgit:org.eclipse.jgit:5.13.0.202109080827-r")
|
||||||
|
classpath("org.kohsuke:github-api:1.301")
|
||||||
|
classpath("org.jetbrains:markdown:0.2.4")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
antlr
|
||||||
|
java
|
||||||
|
kotlin("jvm") version "1.5.10"
|
||||||
|
|
||||||
|
id("org.jetbrains.intellij") version "1.3.0"
|
||||||
|
id("org.jetbrains.changelog") version "1.3.1"
|
||||||
|
|
||||||
|
// ktlint linter - read more: https://github.com/JLLeitschuh/ktlint-gradle
|
||||||
|
id("org.jlleitschuh.gradle.ktlint") version "10.2.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import variables from gradle.properties file
|
||||||
|
val javaVersion: String by project
|
||||||
|
val kotlinVersion: String by project
|
||||||
|
val ideaVersion: String by project
|
||||||
|
val downloadIdeaSources: String by project
|
||||||
|
val instrumentPluginCode: String by project
|
||||||
|
val remoteRobotVersion: String by project
|
||||||
|
|
||||||
|
val publishChannels: String by project
|
||||||
|
val publishToken: String by project
|
||||||
|
|
||||||
|
val slackUrl: String by project
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven { url = uri("https://cache-redirector.jetbrains.com/intellij-dependencies") }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
|
||||||
|
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||||
|
|
||||||
|
// https://mvnrepository.com/artifact/com.ensarsarajcic.neovim.java/neovim-api
|
||||||
|
testImplementation("com.ensarsarajcic.neovim.java:neovim-api:0.2.3")
|
||||||
|
testImplementation("com.ensarsarajcic.neovim.java:core-rpc:0.2.3")
|
||||||
|
|
||||||
|
testImplementation("com.intellij.remoterobot:remote-robot:$remoteRobotVersion")
|
||||||
|
testImplementation("com.intellij.remoterobot:remote-fixtures:$remoteRobotVersion")
|
||||||
|
testImplementation("com.automation-remarks:video-recorder-junit:2.0")
|
||||||
|
runtimeOnly("org.antlr:antlr4-runtime:4.9.3")
|
||||||
|
antlr("org.antlr:antlr4:4.9.3")
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
runtimeClasspath {
|
||||||
|
exclude(group = "org.antlr", module = "antlr4")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Compilation
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
// Issue in gradle 7.3
|
||||||
|
val test by getting(Test::class) {
|
||||||
|
isScanForTestClasses = false
|
||||||
|
// Only run tests from classes that end with "Test"
|
||||||
|
include("**/*Test.class")
|
||||||
|
include("**/*test.class")
|
||||||
|
include("**/*Tests.class")
|
||||||
|
exclude("**/ParserTest.class")
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
sourceCompatibility = javaVersion
|
||||||
|
targetCompatibility = javaVersion
|
||||||
|
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = javaVersion
|
||||||
|
apiVersion = "1.4"
|
||||||
|
// allWarningsAsErrors = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileTestKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = javaVersion
|
||||||
|
apiVersion = "1.4"
|
||||||
|
// allWarningsAsErrors = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gradle.projectsEvaluated {
|
||||||
|
tasks.compileJava {
|
||||||
|
// options.compilerArgs.add("-Werror")
|
||||||
|
options.compilerArgs.add("-Xlint:deprecation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Intellij plugin
|
||||||
|
|
||||||
|
intellij {
|
||||||
|
version.set(ideaVersion)
|
||||||
|
pluginName.set("IdeaVim")
|
||||||
|
updateSinceUntilBuild.set(false)
|
||||||
|
downloadSources.set(downloadIdeaSources.toBoolean())
|
||||||
|
instrumentCode.set(instrumentPluginCode.toBoolean())
|
||||||
|
intellijRepository.set("https://www.jetbrains.com/intellij-repository")
|
||||||
|
plugins.set(listOf("java", "AceJump:3.8.4"))
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
downloadRobotServerPlugin {
|
||||||
|
version.set(remoteRobotVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
publishPlugin {
|
||||||
|
channels.set(publishChannels.split(","))
|
||||||
|
token.set(publishToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
runIdeForUiTests {
|
||||||
|
systemProperty("robot-server.port", "8082")
|
||||||
|
systemProperty("ide.mac.message.dialogs.as.sheets", "false")
|
||||||
|
systemProperty("jb.privacy.policy.text", "<!--999.999-->")
|
||||||
|
systemProperty("jb.consents.confirmation.enabled", "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
runPluginVerifier {
|
||||||
|
downloadDir.set("${project.buildDir}/pluginVerifier/ides")
|
||||||
|
teamCityOutputFormat.set(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
generateGrammarSource {
|
||||||
|
maxHeapSize = "128m"
|
||||||
|
arguments.addAll(listOf("-package", "com.maddyhome.idea.vim.vimscript.parser.generated", "-visitor"))
|
||||||
|
outputDirectory = file("src/main/java/com/maddyhome/idea/vim/vimscript/parser/generated")
|
||||||
|
}
|
||||||
|
|
||||||
|
named("compileKotlin") {
|
||||||
|
dependsOn("generateGrammarSource")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Linting
|
||||||
|
|
||||||
|
ktlint {
|
||||||
|
disabledRules.add("no-wildcard-imports")
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Tests
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
test {
|
||||||
|
exclude("**/propertybased/**")
|
||||||
|
exclude("**/longrunning/**")
|
||||||
|
exclude("/ui/**")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Test>("testWithNeovim") {
|
||||||
|
group = "verification"
|
||||||
|
systemProperty("ideavim.nvim.test", "true")
|
||||||
|
exclude("/ui/**")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Test>("testPropertyBased") {
|
||||||
|
group = "verification"
|
||||||
|
include("**/propertybased/**")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Test>("testLongRunning") {
|
||||||
|
group = "verification"
|
||||||
|
include("**/longrunning/**")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Test>("testUi") {
|
||||||
|
group = "verification"
|
||||||
|
include("/ui/**")
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Changelog
|
||||||
|
|
||||||
|
changelog {
|
||||||
|
groups.set(listOf("Features:", "Changes:", "Deprecations:", "Fixes:", "Merged PRs:"))
|
||||||
|
itemPrefix.set("*")
|
||||||
|
path.set("${project.projectDir}/CHANGES.md")
|
||||||
|
unreleasedTerm.set("To Be Released")
|
||||||
|
headerParserRegex.set("\\d\\.\\d+(.\\d+)?".toRegex())
|
||||||
|
// header = { "${project.version}" }
|
||||||
|
// version = "0.60"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("getUnreleasedChangelog") {
|
||||||
|
group = "changelog"
|
||||||
|
doLast {
|
||||||
|
val log = changelog.getUnreleased().toHTML()
|
||||||
|
println(log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Slack notification
|
||||||
|
|
||||||
|
tasks.register("slackNotification") {
|
||||||
|
doLast {
|
||||||
|
if (slackUrl.isBlank()) {
|
||||||
|
println("Slack Url is not defined")
|
||||||
|
return@doLast
|
||||||
|
}
|
||||||
|
val changeLog = changelog.getLatest().toText()
|
||||||
|
val slackDown = DownParser(changeLog, true).toSlack().toString()
|
||||||
|
|
||||||
|
//language=JSON
|
||||||
|
val message = """
|
||||||
|
{
|
||||||
|
"text": "New version of IdeaVim",
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"type": "section",
|
||||||
|
"text": {
|
||||||
|
"type": "mrkdwn",
|
||||||
|
"text": "IdeaVim $version has been released\n$slackDown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
println("Parsed data: $slackDown")
|
||||||
|
val post = URL(slackUrl)
|
||||||
|
with(post.openConnection() as HttpURLConnection) {
|
||||||
|
requestMethod = "POST"
|
||||||
|
doOutput = true
|
||||||
|
setRequestProperty("Content-Type", "application/json")
|
||||||
|
|
||||||
|
outputStream.write(message.toByteArray())
|
||||||
|
|
||||||
|
val postRc = responseCode
|
||||||
|
println("Response code: $postRc")
|
||||||
|
if (postRc == 200) {
|
||||||
|
println(inputStream.bufferedReader().use { it.readText() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Update authors
|
||||||
|
|
||||||
|
tasks.register("updateAuthors") {
|
||||||
|
doLast {
|
||||||
|
val uncheckedEmails = setOf(
|
||||||
|
"aleksei.plate@jetbrains.com",
|
||||||
|
"aleksei.plate@teamcity",
|
||||||
|
"aleksei.plate@TeamCity",
|
||||||
|
"alex.plate@192.168.0.109"
|
||||||
|
)
|
||||||
|
updateAuthors(uncheckedEmails)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val prId: String by project
|
||||||
|
|
||||||
|
tasks.register("updateMergedPr") {
|
||||||
|
doLast {
|
||||||
|
if (project.hasProperty("prId")) {
|
||||||
|
updateMergedPr(prId.toInt())
|
||||||
|
} else {
|
||||||
|
error("Cannot get prId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("updateChangelog") {
|
||||||
|
doLast {
|
||||||
|
updateChangelog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register("testUpdateChangelog") {
|
||||||
|
group = "verification"
|
||||||
|
description = "This is a task to manually assert the correctness of the update tasks"
|
||||||
|
doLast {
|
||||||
|
val changesFile = File("$projectDir/CHANGES.md")
|
||||||
|
val changes = changesFile.readText()
|
||||||
|
|
||||||
|
val changesBuilder = StringBuilder(changes)
|
||||||
|
val insertOffset = setupSection(changes, changesBuilder, "### Changes:")
|
||||||
|
|
||||||
|
changesBuilder.insert(insertOffset, "--Hello--\n")
|
||||||
|
|
||||||
|
changesFile.writeText(changesBuilder.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateChangelog() {
|
||||||
|
println("Start update authors")
|
||||||
|
println(projectDir)
|
||||||
|
val repository = org.eclipse.jgit.lib.RepositoryBuilder().setGitDir(File("$projectDir/.git")).build()
|
||||||
|
val git = org.eclipse.jgit.api.Git(repository)
|
||||||
|
val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!!
|
||||||
|
val messages = git.log().call()
|
||||||
|
.takeWhile {
|
||||||
|
!it.id.name.equals(lastSuccessfulCommit, ignoreCase = true)
|
||||||
|
}
|
||||||
|
.map { it.shortMessage }
|
||||||
|
|
||||||
|
// Collect fixes
|
||||||
|
val newFixes = mutableListOf<Change>()
|
||||||
|
println("Last successful commit: $lastSuccessfulCommit")
|
||||||
|
println("Amount of commits: ${messages.size}")
|
||||||
|
println("Start emails processing")
|
||||||
|
for (message in messages) {
|
||||||
|
println("Processing '$message'...")
|
||||||
|
val lowercaseMessage = message.toLowerCase()
|
||||||
|
val regex = "^fix\\((vim-\\d+)\\):".toRegex()
|
||||||
|
val findResult = regex.find(lowercaseMessage)
|
||||||
|
if (findResult != null) {
|
||||||
|
println("Message matches")
|
||||||
|
val value = findResult.groups[1]!!.value.toUpperCase()
|
||||||
|
val shortMessage = message.drop(findResult.range.last + 1).trim()
|
||||||
|
newFixes += Change(value, shortMessage)
|
||||||
|
} else {
|
||||||
|
println("Message doesn't match")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update changes file
|
||||||
|
val changesFile = File("$projectDir/CHANGES.md")
|
||||||
|
val changes = changesFile.readText()
|
||||||
|
|
||||||
|
val changesBuilder = StringBuilder(changes)
|
||||||
|
val insertOffset = setupSection(changes, changesBuilder, "### Fixes:")
|
||||||
|
|
||||||
|
if (insertOffset < 50) error("Incorrect offset: $insertOffset")
|
||||||
|
|
||||||
|
val firstPartOfChanges = changes.take(insertOffset)
|
||||||
|
val actualFixes = newFixes
|
||||||
|
.filterNot { it.id in firstPartOfChanges }
|
||||||
|
val newUpdates = actualFixes
|
||||||
|
.joinToString("") { "* [${it.id}](https://youtrack.jetbrains.com/issue/${it.id}) ${it.text}\n" }
|
||||||
|
|
||||||
|
changesBuilder.insert(insertOffset, newUpdates)
|
||||||
|
if (actualFixes.isNotEmpty()) {
|
||||||
|
changesFile.writeText(changesBuilder.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateAuthors(uncheckedEmails: Set<String>) {
|
||||||
|
println("Start update authors")
|
||||||
|
println(projectDir)
|
||||||
|
val repository = org.eclipse.jgit.lib.RepositoryBuilder().setGitDir(File("$projectDir/.git")).build()
|
||||||
|
val git = org.eclipse.jgit.api.Git(repository)
|
||||||
|
val lastSuccessfulCommit = System.getenv("SUCCESS_COMMIT")!!
|
||||||
|
val hashesAndEmailes = git.log().call()
|
||||||
|
.takeWhile {
|
||||||
|
!it.id.name.equals(lastSuccessfulCommit, ignoreCase = true)
|
||||||
|
}
|
||||||
|
.associate { it.authorIdent.emailAddress to it.name }
|
||||||
|
|
||||||
|
println("Last successful commit: $lastSuccessfulCommit")
|
||||||
|
println("Amount of commits: ${hashesAndEmailes.size}")
|
||||||
|
println("Emails: ${hashesAndEmailes.keys}")
|
||||||
|
val gitHub = org.kohsuke.github.GitHub.connect()
|
||||||
|
val ghRepository = gitHub.getRepository("JetBrains/ideavim")
|
||||||
|
val users = mutableSetOf<Author>()
|
||||||
|
println("Start emails processing")
|
||||||
|
for ((email, hash) in hashesAndEmailes) {
|
||||||
|
println("Processing '$email'...")
|
||||||
|
if (email in uncheckedEmails) {
|
||||||
|
println("Email '$email' is in unchecked emails. Skip it")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ("dependabot[bot]@users.noreply.github.com" in email) {
|
||||||
|
println("Email '$email' is from dependabot. Skip it")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val user = ghRepository.getCommit(hash).author
|
||||||
|
val htmlUrl = user.htmlUrl.toString()
|
||||||
|
val name = user.name ?: user.login
|
||||||
|
users.add(Author(name, htmlUrl, email))
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Emails processed")
|
||||||
|
val authorsFile = File("$projectDir/AUTHORS.md")
|
||||||
|
val authors = authorsFile.readText()
|
||||||
|
val parser =
|
||||||
|
org.intellij.markdown.parser.MarkdownParser(org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor())
|
||||||
|
val tree = parser.buildMarkdownTreeFromString(authors)
|
||||||
|
|
||||||
|
val contributorsSection = tree.children[24]
|
||||||
|
val existingEmails = mutableSetOf<String>()
|
||||||
|
for (child in contributorsSection.children) {
|
||||||
|
if (child.children.size > 1) {
|
||||||
|
existingEmails.add(
|
||||||
|
child.children[1].children[0].children[2].children[2].getTextInNode(authors).toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newAuthors = users.filterNot { it.mail in existingEmails }
|
||||||
|
if (newAuthors.isEmpty()) return
|
||||||
|
|
||||||
|
val authorNames = newAuthors.joinToString(", ") { it.name }
|
||||||
|
println("::set-output name=authors::$authorNames")
|
||||||
|
|
||||||
|
val insertionString = newAuthors.toMdString()
|
||||||
|
val resultingString = StringBuffer(authors).insert(contributorsSection.endOffset, insertionString).toString()
|
||||||
|
|
||||||
|
authorsFile.writeText(resultingString)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Author>.toMdString(): String {
|
||||||
|
return this.joinToString {
|
||||||
|
"""
|
||||||
|
|
|
||||||
|
|* [![icon][mail]](mailto:${it.mail})
|
||||||
|
| [![icon][github]](${it.url})
|
||||||
|
|
|
||||||
|
| ${it.name}
|
||||||
|
""".trimMargin()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Author(val name: String, val url: String, val mail: String)
|
||||||
|
data class Change(val id: String, val text: String)
|
||||||
|
|
||||||
|
fun updateMergedPr(number: Int) {
|
||||||
|
val gitHub = org.kohsuke.github.GitHub.connect()
|
||||||
|
val repository = gitHub.getRepository("JetBrains/ideavim")
|
||||||
|
val pullRequest = repository.getPullRequest(number)
|
||||||
|
if (pullRequest.user.login == "dependabot[bot]") return
|
||||||
|
|
||||||
|
val changesFile = File("$projectDir/CHANGES.md")
|
||||||
|
val changes = changesFile.readText()
|
||||||
|
|
||||||
|
val changesBuilder = StringBuilder(changes)
|
||||||
|
val insertOffset = setupSection(changes, changesBuilder, "### Merged PRs:")
|
||||||
|
|
||||||
|
if (insertOffset < 50) error("Incorrect offset: $insertOffset")
|
||||||
|
if (pullRequest.user.login == "dependabot[bot]") return
|
||||||
|
|
||||||
|
val prNumber = pullRequest.number
|
||||||
|
val userName = pullRequest.user.name
|
||||||
|
val login = pullRequest.user.login
|
||||||
|
val title = pullRequest.title
|
||||||
|
val section =
|
||||||
|
"* [$prNumber](https://github.com/JetBrains/ideavim/pull/$prNumber) by [$userName](https://github.com/$login): $title\n"
|
||||||
|
changesBuilder.insert(insertOffset, section)
|
||||||
|
|
||||||
|
changesFile.writeText(changesBuilder.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupSection(
|
||||||
|
changes: String,
|
||||||
|
authorsBuilder: StringBuilder,
|
||||||
|
sectionName: String,
|
||||||
|
): Int {
|
||||||
|
val parser =
|
||||||
|
org.intellij.markdown.parser.MarkdownParser(org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor())
|
||||||
|
val tree = parser.buildMarkdownTreeFromString(changes)
|
||||||
|
|
||||||
|
var idx = -1
|
||||||
|
for (index in tree.children.indices) {
|
||||||
|
if (tree.children[index].getTextInNode(changes).startsWith("## ")) {
|
||||||
|
idx = index
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hasToBeReleased = tree.children[idx].getTextInNode(changes).contains("To Be Released")
|
||||||
|
return if (hasToBeReleased) {
|
||||||
|
var mrgIdx = -1
|
||||||
|
for (index in (idx + 1) until tree.children.lastIndex) {
|
||||||
|
val textInNode = tree.children[index].getTextInNode(changes)
|
||||||
|
val foundIndex = textInNode.startsWith(sectionName)
|
||||||
|
if (foundIndex) {
|
||||||
|
var filledPr = index + 2
|
||||||
|
while (tree.children[filledPr].getTextInNode(changes).startsWith("*")) {
|
||||||
|
filledPr++
|
||||||
|
}
|
||||||
|
mrgIdx = tree.children[filledPr].startOffset + 1
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
val currentSectionIndex = sections.indexOf(sectionName)
|
||||||
|
val insertHere = textInNode.startsWith("## ") ||
|
||||||
|
textInNode.startsWith("### ") &&
|
||||||
|
sections.indexOfFirst { textInNode.startsWith(it) }
|
||||||
|
.let { if (it < 0) false else it > currentSectionIndex }
|
||||||
|
if (insertHere) {
|
||||||
|
val section = """
|
||||||
|
$sectionName
|
||||||
|
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
authorsBuilder.insert(tree.children[index].startOffset, section)
|
||||||
|
mrgIdx = tree.children[index].startOffset + (section.length - 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mrgIdx
|
||||||
|
} else {
|
||||||
|
val section = """
|
||||||
|
## To Be Released
|
||||||
|
|
||||||
|
$sectionName
|
||||||
|
|
||||||
|
|
||||||
|
""".trimIndent()
|
||||||
|
authorsBuilder.insert(tree.children[idx].startOffset, section)
|
||||||
|
tree.children[idx].startOffset + (section.length - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val sections = listOf(
|
||||||
|
"### Features:",
|
||||||
|
"### Changes:",
|
||||||
|
"### Fixes:",
|
||||||
|
"### Merged PRs:",
|
||||||
|
)
|
6
config/ktlint/baseline.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<baseline version="1.0">
|
||||||
|
<file name="src/main/java/com/maddyhome/idea/vim/listener/RiderSpecifics.kt">
|
||||||
|
<error line="1" column="1" source="filename" />
|
||||||
|
</file>
|
||||||
|
</baseline>
|
1
doc
248
doc/Emulated-plugins.md
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
Emulated Vim Plugins
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
IdeaVim extensions emulate plugins of the original Vim. In order to use
|
||||||
|
IdeaVim extensions, you have to enable them via this command in your `~/.ideavimrc`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Plug '<extension-github-reference>'
|
||||||
|
```
|
||||||
|
|
||||||
|
If you reuse your existing `.vimrc` file using `source ~/.vimrc`, IdeaVim can parse and enable plugins that are defined
|
||||||
|
using [vim-plug](https://github.com/junegunn/vim-plug) or [vundle](https://github.com/VundleVim/Vundle.vim).
|
||||||
|
No additional set commands in `~/.ideavimrc` are required.
|
||||||
|
If you'd like to disable some plugin that's enabled in `.vimrc`, you can use `set no<extension-name>`
|
||||||
|
in `~/.ideavimrc`. E.g. `set nosurround`.
|
||||||
|
|
||||||
|
Available extensions:
|
||||||
|
|
||||||
|
## easymotion
|
||||||
|
|
||||||
|
* Setup:
|
||||||
|
* Install [IdeaVim-EasyMotion](https://plugins.jetbrains.com/plugin/13360-ideavim-easymotion/)
|
||||||
|
and [AceJump](https://plugins.jetbrains.com/plugin/7086-acejump/) plugins.
|
||||||
|
* `Plug 'easymotion/vim-easymotion'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/easymotion/vim-easymotion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-easymotion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set easymotion</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-easymotion](https://github.com/easymotion/vim-easymotion)
|
||||||
|
* Commands: All commands with the mappings are supported. See the [full list of supported commands](https://github.com/AlexPl292/IdeaVim-EasyMotion#supported-commands).
|
||||||
|
|
||||||
|
## NERDTree
|
||||||
|
* Setup: `Plug 'preservim/nerdtree'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/preservim/nerdtree'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'nerdtree'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set NERDTree</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [NERDTree](https://github.com/preservim/nerdtree)
|
||||||
|
* Commands: [[see here|NERDTree-support]]
|
||||||
|
|
||||||
|
## surround
|
||||||
|
|
||||||
|
* Setup: `Plug 'tpope/vim-surround'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/tpope/vim-surround'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-surround'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set surround</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-surround](https://github.com/tpope/vim-surround)
|
||||||
|
* Commands: `ys`, `cs`, `ds`, `S`
|
||||||
|
|
||||||
|
## multiple-cursors
|
||||||
|
|
||||||
|
* Setup: `Plug 'terryma/vim-multiple-cursors'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/terryma/vim-multiple-cursors'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-multiple-cursors'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set multiple-cursors</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors)
|
||||||
|
* Commands: `<A-n>`, `<A-x>`, `<A-p>`, `g<A-n>`
|
||||||
|
|
||||||
|
## commentary
|
||||||
|
|
||||||
|
* Setup: `Plug 'tpope/vim-commentary'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/tpope/vim-commentary'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-commentary'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=3695'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tomtom/tcomment_vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'tcomment_vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1173'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set commentary</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [commentary.vim](https://github.com/tpope/vim-commentary)
|
||||||
|
* Commands: `gcc`, `gc + motion`, `v_gc`
|
||||||
|
* By [Daniel Leong](https://github.com/dhleong)
|
||||||
|
|
||||||
|
## ReplaceWithRegister
|
||||||
|
|
||||||
|
* Setup: `Plug 'vim-scripts/ReplaceWithRegister'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/vim-scripts/ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/inkarkat/vim-ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'inkarkat/vim-ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-ReplaceWithRegister'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2703'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set ReplaceWithRegister</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister)
|
||||||
|
* Commands: `gr`, `grr`
|
||||||
|
* By [igrekster](https://github.com/igrekster)
|
||||||
|
|
||||||
|
## argtextobj
|
||||||
|
|
||||||
|
* Setup:
|
||||||
|
* `Plug 'vim-scripts/argtextobj.vim'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'argtextobj.vim'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set argtextobj</code>
|
||||||
|
</details>
|
||||||
|
* By default, only the arguments inside parenthesis are considered. To extend the functionality
|
||||||
|
to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
|
||||||
|
list of colon-separated pairs (same as VIM's `matchpairs` option), like
|
||||||
|
`let g:argtextobj_pairs="(:),{:},<:>"`. The order of pairs matters when
|
||||||
|
handling symbols that can also be operators: `func(x << 5, 20) >> 17`. To handle
|
||||||
|
this syntax parenthesis, must come before angle brackets in the list.
|
||||||
|
* Emulates [argtextobj.vim](https://www.vim.org/scripts/script.php?script_id=2699)
|
||||||
|
* Additional text objects: `aa`, `ia`
|
||||||
|
|
||||||
|
## exchange
|
||||||
|
|
||||||
|
* Setup: `Plug 'tommcdo/vim-exchange'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-exchange'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set exchange</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-exchange](https://github.com/tommcdo/vim-exchange)
|
||||||
|
* Commands: `cx`, `cxx`, `X`, `cxc`
|
||||||
|
* By [fan-tom](https://github.com/fan-tom)
|
||||||
|
|
||||||
|
## textobj-entire
|
||||||
|
|
||||||
|
* Setup: `Plug 'kana/vim-textobj-entire'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/kana/vim-textobj-entire'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-textobj-entire'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2610'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set textobj-entire</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-textobj-entire](https://github.com/kana/vim-textobj-entire)
|
||||||
|
* Additional text objects: `ae`, `ie`
|
||||||
|
* By [Alexandre Grison](https://github.com/agrison)
|
||||||
|
|
||||||
|
## highlightedyank
|
||||||
|
|
||||||
|
* Setup:
|
||||||
|
* `Plug 'machakann/vim-highlightedyank'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-highlightedyank'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set highlightedyank</code>
|
||||||
|
</details>
|
||||||
|
* if you want to optimize highlight duration, assign a time in milliseconds:
|
||||||
|
`let g:highlightedyank_highlight_duration = "1000"`
|
||||||
|
A negative number makes the highlight persistent.
|
||||||
|
`let g:highlightedyank_highlight_duration = "-1"`
|
||||||
|
* if you want to change background color of highlight you can provide the rgba of the color you want e.g.
|
||||||
|
`let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
|
||||||
|
* Emulates [vim-highlightedyank](https://github.com/machakann/vim-highlightedyank)
|
||||||
|
* By [KostkaBrukowa](https://github.com/KostkaBrukowa)
|
||||||
|
|
||||||
|
## vim-paragraph-motion
|
||||||
|
|
||||||
|
* Setup: `Plug 'dbakker/vim-paragraph-motion'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/dbakker/vim-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'https://github.com/vim-scripts/Improved-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-scripts/Improved-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'Improved-paragraph-motion'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set vim-paragraph-motion</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-paragraph-motion](https://github.com/dbakker/vim-paragraph-motion)
|
||||||
|
|
||||||
|
## vim-indent-object
|
||||||
|
|
||||||
|
* Setup: `Plug 'michaeljsmith/vim-indent-object'`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'https://github.com/michaeljsmith/vim-indent-object'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'vim-indent-object'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set textobj-indent</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [vim-indent-object](https://github.com/michaeljsmith/vim-indent-object)
|
||||||
|
* Additional text objects: `ai`, `ii`, `aI`
|
||||||
|
* By [Shrikant Sharat Kandula](https://github.com/sharat87)
|
||||||
|
|
||||||
|
## matchit.vim
|
||||||
|
|
||||||
|
* Setup: `packadd matchit`
|
||||||
|
* <details>
|
||||||
|
<summary>Alternative vim-plug / vundle syntax</summary>
|
||||||
|
<code>Plug 'vim-matchit'</code>
|
||||||
|
<br/>
|
||||||
|
<code>Plug 'chrisbra/matchit'</code>
|
||||||
|
<br/>
|
||||||
|
<code>set matchit</code>
|
||||||
|
</details>
|
||||||
|
* Emulates [matchit.vim](https://github.com/chrisbra/matchit)
|
||||||
|
* Currently works for HTML/XML and ruby
|
||||||
|
* By [Martin Yzeiri](https://github.com/myzeiri)
|
6
doc/Home.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Welcome to the IdeaVim wiki!
|
||||||
|
|
||||||
|
- List of emulated plugins: [[plugins|Emulated-plugins]]
|
||||||
|
- Examples of `ideajoin` option (also known as "smart join"): [["ideajoin" examples|"ideajoin"-examples]]
|
||||||
|
- List of "set" commands: [["set" commands|"set"-commands]]
|
||||||
|
- Docs about "select" mode in vim: [[select mode|Select-mode]]
|
73
doc/NERDTree-support.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# NERDTree
|
||||||
|
|
||||||
|
IdeaVim supports emulation of the NERDTree plugin. Update your `~/.ideavimrc` to turn it on:
|
||||||
|
```vim
|
||||||
|
Plug 'preservim/nerdtree`
|
||||||
|
```
|
||||||
|
or
|
||||||
|
```vim
|
||||||
|
set NERDTree
|
||||||
|
```
|
||||||
|
Use `set noNERDTree` to disable this extension.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Full list of aliases</summary>
|
||||||
|
|
||||||
|
```vim
|
||||||
|
set NERDTree
|
||||||
|
Plug 'preservim/nerdtree`
|
||||||
|
Plug 'https://github.com/preservim/nerdtree'
|
||||||
|
Plug 'https://github.com/scrooloose/nerdtree'
|
||||||
|
Plug 'scrooloose/nerdtree'
|
||||||
|
Plug 'nerdtree'
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
### Preview
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Click to the the preview</summary>
|
||||||
|
<img src="images/nerdtree.gif" alt="NERDTree example"/>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Supported commands
|
||||||
|
|
||||||
|
- `:NERDTree`
|
||||||
|
- `:NERDTreeFocus`
|
||||||
|
- `:NERDTreeToggle`
|
||||||
|
- `:NERDTreeClose`
|
||||||
|
- `:NERDTreeFind`
|
||||||
|
- `:NERDTreeRefreshRoot`
|
||||||
|
|
||||||
|
| Key | Description | Map Setting |
|
||||||
|
|---------|---------------------------------------------------------|--------------------------------|
|
||||||
|
| `o` | Open files, directories and bookmarks | `g:NERDTreeMapActivateNode` |
|
||||||
|
| `go` | Open selected file, but leave cursor in the NERDTree | `g:NERDTreeMapPreview` |
|
||||||
|
| `t` | Open selected node/bookmark in a new tab | `g:NERDTreeMapOpenInTab` |
|
||||||
|
| `T` | Same as 't' but keep the focus on the current tab | `g:NERDTreeMapOpenInTabSilent` |
|
||||||
|
| `i` | Open selected file in a split window | `g:NERDTreeMapOpenSplit` |
|
||||||
|
| `gi` | Same as i, but leave the cursor on the NERDTree | `g:NERDTreeMapPreviewSplit` |
|
||||||
|
| `s` | Open selected file in a new vsplit | `g:NERDTreeMapOpenVSplit` |
|
||||||
|
| `gs` | Same as s, but leave the cursor on the NERDTree | `g:NERDTreeMapPreviewVSplit` |
|
||||||
|
| `O` | Recursively open the selected directory | `g:NERDTreeMapOpenRecursively` |
|
||||||
|
| `x` | Close the current nodes parent | `g:NERDTreeMapCloseDir` |
|
||||||
|
| `X` | Recursively close all children of the current node | `g:NERDTreeMapCloseChildren` |
|
||||||
|
| `P` | Jump to the root node | `g:NERDTreeMapJumpRoot` |
|
||||||
|
| `p` | Jump to current nodes parent | `g:NERDTreeMapJumpParent` |
|
||||||
|
| `K` | Jump up inside directories at the current tree depth | `g:NERDTreeMapJumpFirstChild` |
|
||||||
|
| `J` | Jump down inside directories at the current tree depth | `g:NERDTreeMapJumpLastChild` |
|
||||||
|
| `<C-J>` | Jump down to next sibling of the current directory | `g:NERDTreeMapJumpNextSibling` |
|
||||||
|
| `<C-K>` | Jump up to previous sibling of the current directory | `g:NERDTreeMapJumpPrevSibling` |
|
||||||
|
| `r` | Recursively refresh the current directory | `g:NERDTreeMapRefresh` |
|
||||||
|
| `R` | Recursively refresh the current root | `g:NERDTreeMapRefreshRoot` |
|
||||||
|
| `m` | Display the NERDTree menu | `g:NERDTreeMapMenu` |
|
||||||
|
| `q` | Close the NERDTree window | `g:NERDTreeMapQuit` |
|
||||||
|
| `A` | Zoom (maximize/minimize) the NERDTree window | `g:NERDTreeMapToggleZoom` |
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
|
||||||
|
If you see the the file is opened automatically on every movement in the Project View (`j`, `k`, etc.)
|
||||||
|
please make sure that you have "Open Files with Single click" disabled.
|
||||||
|
|
||||||
|
<img src="images/disable-one-click.png" alt="Disable one click"/>
|
24
doc/Select-mode.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# FAQ
|
||||||
|
|
||||||
|
## What is select mode?
|
||||||
|
|
||||||
|
This mode is where the selection works the same as system selection. When you start typing, the text in the selected area is removed and replaced by the new characters that are being typed in.
|
||||||
|
|
||||||
|
## Why is select mode enabled during refactoring?
|
||||||
|
|
||||||
|
With the help of the select mode, you can immediately enter the variable name during refactoring. You can go to the beginning or the end of a variable using the arrow keys. If you need to make more complex changes, you can always go back to normal mode with `<ESC>`.
|
||||||
|
|
||||||
|
## What if I want to use visual mode during refactoring?
|
||||||
|
|
||||||
|
Select mode is controlled by the `keymodel`, `selectmode` and `idearefactormode` options. Set `idearefactormode` to `visual` to adjust this behavior.
|
||||||
|
`set idearefactormode=visual`
|
||||||
|
|
||||||
|
## What if I don't want to change the mode during refactoring?
|
||||||
|
|
||||||
|
`set idearefactormode=keep`
|
||||||
|
|
||||||
|
# See Also
|
||||||
|
|
||||||
|
* IdeaVim options: https://github.com/JetBrains/ideavim/blob/master/doc/set-commands.md
|
||||||
|
* Vim documentation about select mode: https://vimhelp.org/visual.txt.html#Select-mode
|
||||||
|
* Stackoverflow explanation: https://vi.stackexchange.com/questions/4891/what-is-the-select-mode-and-when-is-it-relevant-to-use-it
|
58
doc/ideajoin-examples.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
Some examples of join command with `ideajoin` option enabled.
|
||||||
|
Put `set ideajoin` to your `~/.ideavimrc` to enable this functionality.
|
||||||
|
|
||||||
|
* Automatic join concatenated lines:
|
||||||
|
|
||||||
|
```
|
||||||
|
"Hello" + -> "Hello world"
|
||||||
|
" world!"
|
||||||
|
```
|
||||||
|
|
||||||
|
* Nested if's:
|
||||||
|
|
||||||
|
```
|
||||||
|
if (a) { -> if (a && b) {
|
||||||
|
if (b) { ...
|
||||||
|
... }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Comments:
|
||||||
|
|
||||||
|
```
|
||||||
|
// Hello -> // Hello world
|
||||||
|
// world
|
||||||
|
```
|
||||||
|
|
||||||
|
* Remove braces from one line for / if / while:
|
||||||
|
|
||||||
|
```
|
||||||
|
if (fail) { -> if (fail) return;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Kotlin one line method:
|
||||||
|
|
||||||
|
```
|
||||||
|
fun myNumber(): Int { -> fun myNumber(): Int = 42
|
||||||
|
return 42
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Join declaration and initialization:
|
||||||
|
|
||||||
|
```
|
||||||
|
int a; -> int a = 5;
|
||||||
|
a = 5;
|
||||||
|
```
|
||||||
|
|
||||||
|
* Chain call:
|
||||||
|
|
||||||
|
```
|
||||||
|
sb.append("a"); -> sb.append("a").append("b");
|
||||||
|
sb.append("b");
|
||||||
|
```
|
||||||
|
|
||||||
|
And other features provided by the plugins.
|
BIN
doc/images/disable-one-click.png
Normal file
After Width: | Height: | Size: 223 KiB |
BIN
doc/images/nerdtree.gif
Normal file
After Width: | Height: | Size: 32 MiB |
140
doc/set-commands.md
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
List of Supported Set Commands
|
||||||
|
==============================
|
||||||
|
|
||||||
|
The following `:set` commands can appear in `~/.ideavimrc` or be set manually in the command mode:
|
||||||
|
|
||||||
|
'clipboard' 'cb' clipboard options
|
||||||
|
Standard clipboard options plus
|
||||||
|
|
||||||
|
`ideaput` (default on) - IdeaVim ONLY
|
||||||
|
enable native idea paste action for put operations
|
||||||
|
|
||||||
|
'digraph' 'dg' enable the entering of digraphs in Insert mode
|
||||||
|
'gdefault' 'gd' the ":substitute" flag 'g' is by default
|
||||||
|
'history' 'hi' number of command-lines that are remembered
|
||||||
|
'hlsearch' 'hls' highlight matches with the last search pattern
|
||||||
|
'ignorecase' 'ic' ignore case in search patterns
|
||||||
|
'iskeyword' 'isk' defines keywords for commands like 'w', '*', etc.
|
||||||
|
'incsearch' 'is' show where search pattern typed so far matches
|
||||||
|
|
||||||
|
`keymodel` `km` String (default "continueselect,stopselect")
|
||||||
|
|
||||||
|
List of comma separated words, which enable special things that keys
|
||||||
|
can do. These values can be used:
|
||||||
|
startsel Using a shifted special[1] key starts selection (either
|
||||||
|
Select mode or Visual mode, depending on "key" being
|
||||||
|
present in 'selectmode').
|
||||||
|
stopsel Using a NOT-shifted special[1] key stops selection.
|
||||||
|
Automatically enables `stopselect` and `stopvisual`
|
||||||
|
stopselect Using a NOT-shifted special[1] key stops - IdeaVim ONLY
|
||||||
|
select mode and removes selection.
|
||||||
|
stopvisual Using a NOT-shifted special[1] key stops - IdeaVim ONLY
|
||||||
|
visual mode and removes selection.
|
||||||
|
continueselect Using a shifted arrow key doesn't - IdeaVim ONLY
|
||||||
|
start selection, but in select mode
|
||||||
|
acts like startsel is enabled
|
||||||
|
continuevisual Using a shifted arrow key doesn't - IdeaVim ONLY
|
||||||
|
start selection, but in visual mode
|
||||||
|
acts like startsel is enabled
|
||||||
|
|
||||||
|
'matchpairs' 'mps' pairs of characters that "%" can match
|
||||||
|
'maxmapdepth' 'mmd' Maximum depth of mappings
|
||||||
|
'more' 'more' When on, listings pause when the whole screen is filled.
|
||||||
|
'nrformats' 'nf' number formats recognized for CTRL-A command
|
||||||
|
'number' 'nu' print the line number in front of each line
|
||||||
|
'relativenumber' 'rnu' show the line number relative to the line with
|
||||||
|
the cursor
|
||||||
|
'scroll' 'scr' lines to scroll with CTRL-U and CTRL-D
|
||||||
|
'scrolljump' 'sj' minimum number of lines to scroll
|
||||||
|
'scrolloff' 'so' minimum number of lines above and below the cursor
|
||||||
|
'selection' 'sel' what type of selection to use
|
||||||
|
|
||||||
|
`selectmode` `slm` String (default "")
|
||||||
|
|
||||||
|
This is a comma-separated list of words, which specify when to start
|
||||||
|
Select mode instead of Visual mode, when a selection is started.
|
||||||
|
Possible values:
|
||||||
|
mouse when using the mouse
|
||||||
|
key when using shifted special[1] keys
|
||||||
|
cmd when using "v", "V", or <C-V>
|
||||||
|
ideaselection when IDE sets a selection - IdeaVim ONLY
|
||||||
|
(examples: extend selection, wrap with while, etc.)
|
||||||
|
|
||||||
|
`startofline` `sol` When "on" some commands move the cursor to the first non-blank of the line.
|
||||||
|
When off the cursor is kept in the same column (if possible).
|
||||||
|
|
||||||
|
'showmode' 'smd' message on the status line to show current mode
|
||||||
|
'showcmd' 'sc' show (partial) command in the status bar
|
||||||
|
'sidescroll' 'ss' minimum number of columns to scroll horizontally
|
||||||
|
'sidescrolloff' 'siso' min. number of columns to left and right of cursor
|
||||||
|
'smartcase' 'scs' no ignore case when pattern is uppercase
|
||||||
|
'timeout' 'to' use timeout for mapped key sequences
|
||||||
|
'timeoutlen' 'tm' timeout duration for a mapped key sequence
|
||||||
|
'undolevels' 'ul' maximum number of changes that can be undone
|
||||||
|
'viminfo' 'vi' information to remember after restart
|
||||||
|
'visualbell' 'vb' use visual bell instead of beeping
|
||||||
|
'wrapscan' 'ws' searches wrap around the end of file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IdeaVim only commands:
|
||||||
|
|
||||||
|
`ideamarks` `ideamarks` Boolean (default true)
|
||||||
|
|
||||||
|
If true, creation of global mark will trigger creation of IDE's bookmark
|
||||||
|
and vice versa.
|
||||||
|
|
||||||
|
`idearefactormode` `idearefactormode` String(default "select")
|
||||||
|
|
||||||
|
Define the mode that would be enabled during
|
||||||
|
the refactoring (renaming, live template, introduce variable, etc)
|
||||||
|
|
||||||
|
Use one of the following values:
|
||||||
|
- keep - keep the mode that was enabled before starting a refactoring
|
||||||
|
- select - start refactoring in select mode
|
||||||
|
- visual - start refactoring in visual mode
|
||||||
|
|
||||||
|
This option has effect if you are in normal, insert or replace mode before refactoring start.
|
||||||
|
Visual or select mode are not changed.
|
||||||
|
|
||||||
|
|
||||||
|
`ideajoin` `ideajoin` Boolean (default false)
|
||||||
|
|
||||||
|
If true, join command will be performed via IDE
|
||||||
|
See wiki/`ideajoin` examples
|
||||||
|
|
||||||
|
`ideastatusicon` `ideastatusicon` String(default "enabled")
|
||||||
|
|
||||||
|
Define the behavior of IdeaVim icon in the status bar.
|
||||||
|
|
||||||
|
Use one of the following values:
|
||||||
|
- enabled - icon is shown in the status bar
|
||||||
|
- gray - use the gray version of the icon
|
||||||
|
- disabled - hide the icon
|
||||||
|
|
||||||
|
`ideawrite` `ideawrite` String (default "all")
|
||||||
|
"file" or "all". Defines the behaviour of ":w" command.
|
||||||
|
Value "all" enables execution of ":wa" (save all) command on ":w" (save).
|
||||||
|
This feature exists because some IJ options like "Prettier on save" or "ESlint on save"
|
||||||
|
work only with "save all" action. If this option is set to "all", these actions work
|
||||||
|
also with ":w" command.
|
||||||
|
|
||||||
|
`lookupkeys` `lookupkeys` List of strings
|
||||||
|
|
||||||
|
List of keys that should be processed by the IDE during the active lookup (autocompletion).
|
||||||
|
For example, <Tab> and <Enter> are used by the IDE to finish the lookup,
|
||||||
|
but <C-W> should be passed to IdeaVim.
|
||||||
|
Default value:
|
||||||
|
"<Tab>", "<Down>", "<Up>", "<Enter>", "<Left>", "<Right>",
|
||||||
|
"<C-Down>", "<C-Up>", "<PageUp>", "<PageDown>",
|
||||||
|
"<C-J>", "<C-Q>"
|
||||||
|
|
||||||
|
`ideavimsupport` `ideavimsupport` List of strings (default "dialog")
|
||||||
|
|
||||||
|
Define the list of additional buffers where IdeaVim is enabled.
|
||||||
|
|
||||||
|
- dialog - enable IdeaVim in dialogs
|
||||||
|
- singleline - enable IdeaVim in single line editors (not suggested)
|
||||||
|
|
||||||
|
----------
|
||||||
|
[1] - cursor keys, <End>, <Home>, <PageUp> and <PageDown>
|
34
doc/sethandler.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Configuring conflicting keys via .ideavimrc
|
||||||
|
|
||||||
|
IdeaVim allows defining handlers for the shortcuts that exist for both IDE and Vim (e.g. `<C-C>`).
|
||||||
|
|
||||||
|
```vim
|
||||||
|
" Use ctrl-c as an ide shortcut in normal and visual modes
|
||||||
|
sethandler <C-C> n-v:ide i:vim
|
||||||
|
```
|
||||||
|
|
||||||
|
This option consist of an optional shortcut and a list of space separated list of handlers:
|
||||||
|
`mode-list:handler mode-list:handler ...`
|
||||||
|
The `mode-list` is a dash separated list of modes that is similar to `guicursor` notation
|
||||||
|
and defines the following modes:
|
||||||
|
- n - normal mode
|
||||||
|
- i - insert mode
|
||||||
|
- x - visual mode
|
||||||
|
- v - visual and select modes
|
||||||
|
- a - all modes
|
||||||
|
|
||||||
|
The `handler` is an argument that may accept the following values:
|
||||||
|
- ide - use IDE handler
|
||||||
|
- vim - use Vim handler
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- `n:ide` - use IDE handler in normal mode
|
||||||
|
- `i-v:vim` - use Vim handler in normal, visual, and select modes
|
||||||
|
- `a:ide` - use IDE handler in all modes
|
||||||
|
|
||||||
|
By using `sethandler` you can define handlers:
|
||||||
|
- For a single shortcut: `sethandler <C-A> n:vim i-x:ide` - use Vim handler in normal mode and IDE handler in insert and visual modes,
|
||||||
|
- For all shortcuts: `sethandler n:vim i:ide` - use Vim handlers in normal mode and IDE handlers in insert mode.
|
||||||
|
|
||||||
|
If the definition of the handler is missing for some mode, it defaults to `vim`:
|
||||||
|
`sethandler <C-X> i:ide` - use IDE handler in insert mode and Vim handler in all other modes.
|
@@ -4,10 +4,15 @@ ideaVersion=LATEST-EAP-SNAPSHOT
|
|||||||
downloadIdeaSources=true
|
downloadIdeaSources=true
|
||||||
instrumentPluginCode=true
|
instrumentPluginCode=true
|
||||||
version=SNAPSHOT
|
version=SNAPSHOT
|
||||||
javaVersion=1.8
|
javaVersion=11
|
||||||
kotlinVersion=1.3.71
|
remoteRobotVersion=0.11.10
|
||||||
publishUsername=username
|
|
||||||
|
# Please don't forget to update kotlin version in buildscript section
|
||||||
|
kotlinVersion=1.5.10
|
||||||
publishToken=token
|
publishToken=token
|
||||||
publishChannels=eap
|
publishChannels=eap
|
||||||
|
|
||||||
slackUrl=
|
slackUrl=
|
||||||
|
|
||||||
|
# Gradle settings
|
||||||
|
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
269
gradlew
vendored
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -17,67 +17,101 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@@ -106,80 +140,95 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
warn "Could not query maximum file descriptor limit"
|
||||||
fi
|
esac
|
||||||
ulimit -n $MAX_FD
|
case $MAX_FD in #(
|
||||||
if [ $? -ne 0 ] ; then
|
'' | soft) :;; #(
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
*)
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
else
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
20
qodana.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
version: 1.0
|
||||||
|
profile:
|
||||||
|
name: Qodana
|
||||||
|
exclude:
|
||||||
|
- name: MoveVariableDeclarationIntoWhen
|
||||||
|
- name: PluginXmlValidity
|
||||||
|
- name: RedundantThrows
|
||||||
|
- name: SuperTearDownInFinally
|
||||||
|
- name: UnusedReturnValue
|
||||||
|
- name: All
|
||||||
|
paths:
|
||||||
|
- build.gradle
|
||||||
|
- gradle/wrapper/gradle-wrapper.properties
|
||||||
|
- resources/icons/youtrack.svg
|
||||||
|
- src/com/maddyhome/idea/vim/ex/vimscript/VimScriptCommandHandler.java
|
||||||
|
- src/com/maddyhome/idea/vim/helper/SearchHelper.java
|
||||||
|
- src/com/maddyhome/idea/vim/regexp/RegExp.java
|
||||||
|
- test/org/jetbrains/plugins/ideavim/propertybased/samples/JavaText.kt
|
||||||
|
- test/org/jetbrains/plugins/ideavim/propertybased/samples/LoremText.kt
|
||||||
|
- test/org/jetbrains/plugins/ideavim/propertybased/samples/SimpleText.kt
|
@@ -1,71 +0,0 @@
|
|||||||
<idea-plugin>
|
|
||||||
<extensions defaultExtensionNs="IdeaVIM">
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.ActionListHandler" names="actionlist"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.AsciiHandler" names="as[cii]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.CmdFilterHandler" names="!"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.CmdHandler" names="com[mand]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.CmdClearHandler" names="comc[lear]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.CopyTextHandler" names="co[py],t"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.DelCmdHandler" names="delc[ommand]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.DeleteLinesHandler" names="d[elete]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.DeleteMarksHandler" names="delm[arks]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.DigraphHandler" names="dig[raphs]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.DumpLineHandler" names="dump[line]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.EditFileHandler" names="bro[wse],e[dit]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.ActionHandler" names="action"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.EchoHandler" names="ec[ho]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.ExitHandler" names="qa[ll],quita[ll],wqa[ll],xa[ll]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.FileHandler" names="f[ile]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.FindClassHandler" names="cla[ss]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.FindFileHandler" names="fin[d]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.FindSymbolHandler" names="sym[bol]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.GotoCharacterHandler" names="go[to]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.HelpHandler" names="h[elp]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.HistoryHandler" names="his[tory]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JoinLinesHandler" names="j[oin]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.JumpsHandler" names="ju[mps]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.LetHandler" names="let"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.MapHandler"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.UnMapHandler"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.mapping.MapClearHandler"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarkHandler" names="ma[rk],k"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MarksHandler" names="marks"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.MoveTextHandler" names="m[ove]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.NextFileHandler" names="n[ext]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.NoHLSearchHandler" names="noh[lsearch]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.OnlyHandler" names="on[ly]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PreviousFileHandler" names="N[ext],prev[ious]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PromptFindHandler" names="pro[mptfind]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PromptReplaceHandler" names="promptr[epl]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PutLinesHandler" names="pu[t]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.QuitHandler" names="q[uit],clo[se],hid[e]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.RedoHandler" names="red[o]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.RegistersHandler" names="di[splay],reg[isters]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.RepeatHandler" names="@"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SelectFileHandler" names="argu[ment]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SelectFirstFileHandler" names="fir[st],rew[ind]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SelectLastFileHandler" names="la[st]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SetHandler" names="se[t]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.ShiftLeftHandler"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.ShiftRightHandler"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SourceHandler" names="so[urce]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SortHandler" names="sor[t]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SplitHandler" names="vs[plit],sp[lit]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.SubstituteHandler" names="s[ubstitute],&,~"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.UndoHandler" names="u[ndo]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.WriteAllHandler" names="wa[ll]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.WriteHandler" names="w[rite]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.WriteNextFileHandler" names="wn[ext]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.WritePreviousFileHandler" names="wN[ext],wp[revious]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.WriteQuitHandler" names="wq,exi[t],x[it]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.YankLinesHandler" names="y[ank]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.ShellHandler" names="sh[ell]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.NextTabHandler" names="tabn[ext]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PreviousTabHandler" names="tabp[revious],tabN[ext]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.TabOnlyHandler" names="tabo[nly]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.TabCloseHandler" names="tabc[lose]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.BufferListHandler" names="buffers,ls,files"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.BufferHandler" names="b[uffer]"/>
|
|
||||||
<vimExCommand implementation="com.maddyhome.idea.vim.ex.handler.PlugHandler" names="Plug[in]"/>
|
|
||||||
</extensions>
|
|
||||||
</idea-plugin>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" width="16" height="16">
|
|
||||||
<path
|
|
||||||
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 824 B |
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.action.motion.leftright
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.Command
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import com.maddyhome.idea.vim.helper.inInsertMode
|
|
||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
|
||||||
import com.maddyhome.idea.vim.helper.vimLastColumn
|
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionLastColumnAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val motionType: MotionType = MotionType.INCLUSIVE
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
var allow = false
|
|
||||||
if (editor.inInsertMode) {
|
|
||||||
allow = true
|
|
||||||
} else if (editor.inVisualMode) {
|
|
||||||
val opt = OptionsManager.selection
|
|
||||||
if (opt.value != "old") {
|
|
||||||
allow = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret, count - 1, allow)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postMove(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
cmd: Command) {
|
|
||||||
caret.vimLastColumn = MotionGroup.LAST_COLUMN
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun preMove(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
cmd: Command) {
|
|
||||||
caret.vimLastColumn = MotionGroup.LAST_COLUMN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MotionLastColumnInsertAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_STROKE)
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
var allow = false
|
|
||||||
if (editor.inInsertMode) {
|
|
||||||
allow = true
|
|
||||||
} else if (editor.inVisualMode) {
|
|
||||||
val opt = OptionsManager.selection
|
|
||||||
if (opt.value != "old") {
|
|
||||||
allow = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return VimPlugin.getMotion().moveCaretToLineEndOffset(editor, caret, count - 1, allow)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postMove(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
cmd: Command) {
|
|
||||||
caret.vimLastColumn = MotionGroup.LAST_COLUMN
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun preMove(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
cmd: Command) {
|
|
||||||
caret.vimLastColumn = MotionGroup.LAST_COLUMN
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.leftright
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionLeftMatchCharAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.DIGRAPH
|
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_ALLOW_DIGRAPH)
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
if (argument == null) {
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
return caret.offset
|
|
||||||
}
|
|
||||||
val res = VimPlugin.getMotion().moveCaretToNextCharacterOnLine(editor, caret, -count, argument.character)
|
|
||||||
VimPlugin.getMotion().setLastFTCmd(MotionGroup.LAST_F, argument.character)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.leftright
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionLeftTillMatchCharAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.DIGRAPH
|
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_ALLOW_DIGRAPH)
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
if (argument == null) {
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
return caret.offset
|
|
||||||
}
|
|
||||||
val res = VimPlugin.getMotion().moveCaretToBeforeNextCharacterOnLine(editor, caret, -count, argument.character)
|
|
||||||
VimPlugin.getMotion().setLastFTCmd(MotionGroup.LAST_T, argument.character)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.leftright
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionRightMatchCharAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.DIGRAPH
|
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_ALLOW_DIGRAPH)
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
if (argument == null) {
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
return caret.offset
|
|
||||||
}
|
|
||||||
val res = VimPlugin.getMotion().moveCaretToNextCharacterOnLine(editor, caret, count, argument.character)
|
|
||||||
VimPlugin.getMotion().setLastFTCmd(MotionGroup.LAST_f, argument.character)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.INCLUSIVE
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.leftright
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionRightTillMatchCharAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val argumentType: Argument.Type = Argument.Type.DIGRAPH
|
|
||||||
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_ALLOW_DIGRAPH)
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
if (argument == null) {
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
return caret.offset
|
|
||||||
}
|
|
||||||
val res = VimPlugin.getMotion().moveCaretToBeforeNextCharacterOnLine(editor, caret, count, argument.character)
|
|
||||||
VimPlugin.getMotion().setLastFTCmd(MotionGroup.LAST_t, argument.character)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.INCLUSIVE
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.screen
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionFirstScreenLineAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_JUMP)
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.LINE_WISE
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
return VimPlugin.getMotion().moveCaretToFirstScreenLine(editor, count)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.screen
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class MotionLastScreenLineAction : MotionActionHandler.ForEachCaret() {
|
|
||||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_JUMP)
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.LINE_WISE
|
|
||||||
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
caret: Caret,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
return VimPlugin.getMotion().moveCaretToLastScreenLine(editor, count)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.tabs
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author oleg
|
|
||||||
*/
|
|
||||||
class MotionNextTabAction : MotionActionHandler.SingleExecution() {
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
return VimPlugin.getMotion().moveCaretGotoNextTab(editor, context, rawCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.INCLUSIVE
|
|
||||||
}
|
|
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.action.motion.tabs
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
|
||||||
import com.maddyhome.idea.vim.command.MotionType
|
|
||||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author oleg
|
|
||||||
*/
|
|
||||||
class MotionPreviousTabAction : MotionActionHandler.SingleExecution() {
|
|
||||||
override fun getOffset(editor: Editor,
|
|
||||||
context: DataContext,
|
|
||||||
count: Int,
|
|
||||||
rawCount: Int,
|
|
||||||
argument: Argument?): Int {
|
|
||||||
return VimPlugin.getMotion().moveCaretGotoPreviousTab(editor, context, rawCount)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val motionType: MotionType = MotionType.INCLUSIVE
|
|
||||||
}
|
|
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex
|
|
||||||
|
|
||||||
data class CommandName(val required: String, val optional: String = "")
|
|
||||||
|
|
||||||
fun commands(vararg commands: String) = commands.map { command ->
|
|
||||||
val openBracketIndex = command.indexOf('[')
|
|
||||||
if (openBracketIndex < 0) CommandName(command)
|
|
||||||
else CommandName(command.take(openBracketIndex), command.substring(openBracketIndex + 1, command.lastIndex))
|
|
||||||
}.toTypedArray()
|
|
||||||
|
|
||||||
fun flags(
|
|
||||||
rangeFlag: CommandHandler.RangeFlag,
|
|
||||||
argumentFlag: CommandHandler.ArgumentFlag,
|
|
||||||
access: CommandHandler.Access,
|
|
||||||
vararg flags: CommandHandler.Flag
|
|
||||||
) = CommandHandlerFlags(rangeFlag, argumentFlag, access, flags.toSet())
|
|
@@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.util.Ref
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
|
||||||
import com.maddyhome.idea.vim.helper.Msg
|
|
||||||
import com.maddyhome.idea.vim.helper.exitVisualMode
|
|
||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
|
||||||
import com.maddyhome.idea.vim.helper.noneOfEnum
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for all Ex command handlers.
|
|
||||||
*/
|
|
||||||
sealed class CommandHandler {
|
|
||||||
|
|
||||||
abstract val argFlags: CommandHandlerFlags
|
|
||||||
protected open val optFlags: EnumSet<CommandFlags> = noneOfEnum()
|
|
||||||
|
|
||||||
abstract class ForEachCaret : CommandHandler() {
|
|
||||||
abstract fun execute(editor: Editor, caret: Caret, context: DataContext, cmd: ExCommand): Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class SingleExecution : CommandHandler() {
|
|
||||||
abstract fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class RangeFlag {
|
|
||||||
/**
|
|
||||||
* Indicates that a range must be specified with this command
|
|
||||||
*/
|
|
||||||
RANGE_REQUIRED,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that a range is optional for this command
|
|
||||||
*/
|
|
||||||
RANGE_OPTIONAL,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that a range can't be specified for this command
|
|
||||||
*/
|
|
||||||
RANGE_FORBIDDEN,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that the command takes a count, not a range - effects default
|
|
||||||
* Works like RANGE_OPTIONAL
|
|
||||||
*/
|
|
||||||
RANGE_IS_COUNT
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class ArgumentFlag {
|
|
||||||
/**
|
|
||||||
* Indicates that an argument must be specified with this command
|
|
||||||
*/
|
|
||||||
ARGUMENT_REQUIRED,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that an argument is optional for this command
|
|
||||||
*/
|
|
||||||
ARGUMENT_OPTIONAL,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that an argument can't be specified for this command
|
|
||||||
*/
|
|
||||||
ARGUMENT_FORBIDDEN
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Access {
|
|
||||||
/**
|
|
||||||
* Indicates that this is a command that modifies the editor
|
|
||||||
*/
|
|
||||||
WRITABLE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that this command does not modify the editor
|
|
||||||
*/
|
|
||||||
READ_ONLY,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that this command handles writability by itself
|
|
||||||
*/
|
|
||||||
SELF_SYNCHRONIZED
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Flag {
|
|
||||||
DONT_SAVE_LAST,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This command should not exit visual mode.
|
|
||||||
*
|
|
||||||
* Vim exits visual mode before command execution, but in this case :action will work incorrect.
|
|
||||||
* With this flag visual mode will not be exited while command execution.
|
|
||||||
*/
|
|
||||||
SAVE_VISUAL
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a command. The range and arguments are validated first.
|
|
||||||
*
|
|
||||||
* @param editor The editor to run the command in
|
|
||||||
* @param context The data context
|
|
||||||
* @param cmd The command as entered by the user
|
|
||||||
* @param count The count entered by the user prior to the command
|
|
||||||
* @throws ExException if the range or argument is invalid or unable to run the command
|
|
||||||
*/
|
|
||||||
@Throws(ExException::class)
|
|
||||||
fun process(editor: Editor, context: DataContext, cmd: ExCommand, count: Int): Boolean {
|
|
||||||
|
|
||||||
checkArgs(cmd)
|
|
||||||
|
|
||||||
if (editor.inVisualMode && Flag.SAVE_VISUAL !in argFlags.flags) {
|
|
||||||
editor.exitVisualMode()
|
|
||||||
}
|
|
||||||
|
|
||||||
val res = Ref.create(true)
|
|
||||||
try {
|
|
||||||
when (this) {
|
|
||||||
is ForEachCaret -> {
|
|
||||||
editor.caretModel.runForEachCaret({ caret ->
|
|
||||||
var i = 0
|
|
||||||
while (i++ < count && res.get()) {
|
|
||||||
res.set(execute(editor, caret, context, cmd))
|
|
||||||
}
|
|
||||||
}, true)
|
|
||||||
}
|
|
||||||
is SingleExecution -> {
|
|
||||||
var i = 0
|
|
||||||
while (i++ < count && res.get()) {
|
|
||||||
res.set(execute(editor, context, cmd))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res.get()) {
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
}
|
|
||||||
return res.get()
|
|
||||||
} catch (e: ExException) {
|
|
||||||
VimPlugin.showMessage(e.message)
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun checkArgs(cmd: ExCommand) {
|
|
||||||
// No range allowed
|
|
||||||
if (RangeFlag.RANGE_FORBIDDEN == argFlags.rangeFlag && cmd.ranges.size() != 0) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_norange))
|
|
||||||
throw NoRangeAllowedException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RangeFlag.RANGE_REQUIRED == argFlags.rangeFlag && cmd.ranges.size() == 0) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_rangereq))
|
|
||||||
throw MissingRangeException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RangeFlag.RANGE_IS_COUNT == argFlags.rangeFlag) {
|
|
||||||
cmd.ranges.setDefaultLine(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Argument required
|
|
||||||
if (ArgumentFlag.ARGUMENT_REQUIRED == argFlags.argumentFlag && cmd.argument.isEmpty()) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_argreq))
|
|
||||||
throw MissingArgumentException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ArgumentFlag.ARGUMENT_FORBIDDEN == argFlags.argumentFlag && cmd.argument.isNotEmpty()) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_argforb))
|
|
||||||
throw NoArgumentAllowedException()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class CommandHandlerFlags(
|
|
||||||
val rangeFlag: CommandHandler.RangeFlag,
|
|
||||||
val argumentFlag: CommandHandler.ArgumentFlag,
|
|
||||||
val access: CommandHandler.Access,
|
|
||||||
val flags: Set<CommandHandler.Flag>
|
|
||||||
)
|
|
@@ -1,522 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.ex
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.diagnostic.debug
|
|
||||||
import com.intellij.openapi.diagnostic.logger
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.extensions.ExtensionPointChangeListener
|
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName
|
|
||||||
import com.intellij.openapi.util.ThrowableComputable
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.common.GoalCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.handler.GotoLineHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Range.Companion.createRange
|
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Ranges
|
|
||||||
import com.maddyhome.idea.vim.group.HistoryGroup
|
|
||||||
import com.maddyhome.idea.vim.group.RegisterGroup
|
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper.message
|
|
||||||
import com.maddyhome.idea.vim.helper.Msg
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maintains a tree of Ex commands based on the required and optional parts of the command names. Parses and
|
|
||||||
* executes Ex commands entered by the user.
|
|
||||||
*/
|
|
||||||
object CommandParser {
|
|
||||||
private const val MAX_RECURSION = 100
|
|
||||||
private val TRIM_WHITESPACE = Pattern.compile("[ \\t]*(.*)[ \\t\\n\\r]+", Pattern.DOTALL)
|
|
||||||
val EX_COMMAND_EP = ExtensionPointName.create<ExBeanClass>("IdeaVIM.vimExCommand")
|
|
||||||
private val logger = logger<CommandParser>()
|
|
||||||
|
|
||||||
private val root = CommandNode()
|
|
||||||
|
|
||||||
fun unregisterHandlers() {
|
|
||||||
root.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers all the supported Ex commands
|
|
||||||
*/
|
|
||||||
fun registerHandlers() {
|
|
||||||
EX_COMMAND_EP.extensions().forEach(ExBeanClass::register)
|
|
||||||
registerEpListener()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerEpListener() {
|
|
||||||
// IdeaVim doesn't support contribution to ex_command_ep extension point, so technically we can skip this update,
|
|
||||||
// but let's support dynamic plugins in a more classic way and reload handlers on every EP change.
|
|
||||||
EX_COMMAND_EP.getPoint(null).addExtensionPointListener(ExtensionPointChangeListener {
|
|
||||||
unregisterHandlers()
|
|
||||||
registerHandlers()
|
|
||||||
}, false, VimPlugin.getInstance())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to rerun the last Ex command, if any
|
|
||||||
*
|
|
||||||
* @param editor The editor to run the command in
|
|
||||||
* @param context The data context
|
|
||||||
* @param count The number of times to run the command
|
|
||||||
* @return True if the command succeeded, false if it failed or there was no previous command
|
|
||||||
* @throws ExException if any part of the command was invalid
|
|
||||||
*/
|
|
||||||
@kotlin.jvm.Throws(ExException::class)
|
|
||||||
fun processLastCommand(editor: Editor, context: DataContext, count: Int): Boolean {
|
|
||||||
val reg = VimPlugin.getRegister().getRegister(':') ?: return false
|
|
||||||
val text = reg.text ?: return false
|
|
||||||
processCommand(editor, context, text, count)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse and execute an Ex command entered by the user
|
|
||||||
*
|
|
||||||
* @param editor The editor to run the command in
|
|
||||||
* @param context The data context
|
|
||||||
* @param cmd The text entered by the user
|
|
||||||
* @param count The count entered before the colon
|
|
||||||
* @throws ExException if any part of the command is invalid or unknown
|
|
||||||
*/
|
|
||||||
@kotlin.jvm.Throws(ExException::class)
|
|
||||||
fun processCommand(editor: Editor, context: DataContext, cmd: String, count: Int) {
|
|
||||||
processCommand(editor, context, cmd, count, MAX_RECURSION)
|
|
||||||
}
|
|
||||||
|
|
||||||
@kotlin.jvm.Throws(ExException::class)
|
|
||||||
private fun processCommand(
|
|
||||||
editor: Editor, context: DataContext, cmd: String,
|
|
||||||
count: Int, aliasCountdown: Int
|
|
||||||
) {
|
|
||||||
// Nothing entered
|
|
||||||
if (cmd.isEmpty()) {
|
|
||||||
logger.warn("CMD is empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only save the command to the history if it is at the top of the stack.
|
|
||||||
// We don't want to save the aliases that will be executed, only the actual
|
|
||||||
// user input.
|
|
||||||
if (aliasCountdown == MAX_RECURSION) {
|
|
||||||
// Save the command history
|
|
||||||
VimPlugin.getHistory().addEntry(HistoryGroup.COMMAND, cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is a command alias for the entered text, then process the alias and return that
|
|
||||||
// instead of the original command.
|
|
||||||
if (VimPlugin.getCommand().isAlias(cmd)) {
|
|
||||||
if (aliasCountdown > 0) {
|
|
||||||
val commandAlias = VimPlugin.getCommand().getAliasCommand(cmd, count)
|
|
||||||
when (commandAlias) {
|
|
||||||
is GoalCommand.Ex -> {
|
|
||||||
if (commandAlias.command.isEmpty()) {
|
|
||||||
logger.warn("Command alias is empty")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
processCommand(editor, context, commandAlias.command, count, aliasCountdown - 1)
|
|
||||||
}
|
|
||||||
is GoalCommand.Call -> commandAlias.handler.execute(editor, context)
|
|
||||||
}.let { }
|
|
||||||
} else {
|
|
||||||
VimPlugin.showMessage(message("recursion.detected.maximum.alias.depth.reached"))
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
logger.warn("Recursion detected, maximum alias depth reached. ")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the command
|
|
||||||
val command = parse(cmd)
|
|
||||||
val handler = getCommandHandler(command)
|
|
||||||
if (handler == null) {
|
|
||||||
val message = message(Msg.NOT_EX_CMD, command.command)
|
|
||||||
throw InvalidCommandException(message, cmd)
|
|
||||||
}
|
|
||||||
if (handler.argFlags.access === CommandHandler.Access.WRITABLE && !editor.document.isWritable) {
|
|
||||||
VimPlugin.indicateError()
|
|
||||||
logger.info("Trying to modify readonly document")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the command
|
|
||||||
val runCommand = ThrowableComputable<Any?, ExException> {
|
|
||||||
val ok = handler.process(editor, context, command, count)
|
|
||||||
if (ok && !handler.argFlags.flags.contains(CommandHandler.Flag.DONT_SAVE_LAST)) {
|
|
||||||
VimPlugin.getRegister().storeTextSpecial(RegisterGroup.LAST_COMMAND_REGISTER, cmd)
|
|
||||||
}
|
|
||||||
null
|
|
||||||
}
|
|
||||||
when (handler.argFlags.access) {
|
|
||||||
CommandHandler.Access.WRITABLE -> ApplicationManager.getApplication().runWriteAction(runCommand)
|
|
||||||
CommandHandler.Access.READ_ONLY -> ApplicationManager.getApplication().runReadAction(runCommand)
|
|
||||||
CommandHandler.Access.SELF_SYNCHRONIZED -> runCommand.compute()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCommandHandler(command: ExCommand): CommandHandler? {
|
|
||||||
val cmd = command.command
|
|
||||||
// If there is no command, just a range, use the 'goto line' handler
|
|
||||||
if (cmd.isEmpty()) {
|
|
||||||
return GotoLineHandler()
|
|
||||||
}
|
|
||||||
// See if the user entered a supported command by checking each character entered
|
|
||||||
var node: CommandNode = root
|
|
||||||
for (element in cmd) {
|
|
||||||
node = node.getChild(element) ?: return null
|
|
||||||
}
|
|
||||||
val handlerHolder = node.commandHandler
|
|
||||||
return handlerHolder?.instance
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the text entered by the user. This does not include the leading colon.
|
|
||||||
*
|
|
||||||
* @param cmd The user entered text
|
|
||||||
* @return The parse result
|
|
||||||
* @throws ExException if the text is syntactically incorrect
|
|
||||||
*/
|
|
||||||
@kotlin.jvm.Throws(ExException::class)
|
|
||||||
fun parse(cmd: String): ExCommand {
|
|
||||||
// This is a complicated state machine that should probably be rewritten
|
|
||||||
logger.debug { "processing `$cmd'" }
|
|
||||||
|
|
||||||
var state = State.START
|
|
||||||
val ranges = Ranges() // The list of ranges
|
|
||||||
val command = StringBuilder() // The command
|
|
||||||
val argument = StringBuilder() // The command's argument(s)
|
|
||||||
var location: StringBuffer? = null // The current range text
|
|
||||||
var offsetSign = 1 // Sign of current range offset
|
|
||||||
var offsetNumber = 0 // The value of the current range offset
|
|
||||||
var offsetTotal = 0 // The sum of all the current range offsets
|
|
||||||
var move = false // , vs. ; separated ranges (true=; false=,)
|
|
||||||
var patternType = 0.toChar() // ? or /
|
|
||||||
var backCount = 0 // Number of backslashes in a row in a pattern
|
|
||||||
var inBrackets = false // If inside [ ] range in a pattern
|
|
||||||
var error = ""
|
|
||||||
|
|
||||||
// Loop through each character. Treat the end of the string as a newline character
|
|
||||||
for (i in 0..cmd.length) {
|
|
||||||
var reprocess = true // Should the current character be reprocessed after a state change?
|
|
||||||
val ch = if (i == cmd.length) '\n' else cmd[i]
|
|
||||||
loop@ while (reprocess) {
|
|
||||||
when (state) {
|
|
||||||
State.START -> if (Character.isLetter(ch) || "~<>@=#*&!".indexOf(ch) >= 0) {
|
|
||||||
state = State.COMMAND
|
|
||||||
} else if (ch == ' ') {
|
|
||||||
state = State.START
|
|
||||||
reprocess = false
|
|
||||||
} else {
|
|
||||||
state = State.RANGE
|
|
||||||
}
|
|
||||||
State.COMMAND -> // For commands that start with a non-letter, treat other non-letter characters as part of
|
|
||||||
// the argument except for !, <, or >
|
|
||||||
if (Character.isLetter(ch) ||
|
|
||||||
command.isEmpty() && "~<>@=#*&!".indexOf(ch) >= 0 ||
|
|
||||||
command.isNotEmpty() && ch == command[command.length - 1] && "<>".indexOf(ch) >= 0
|
|
||||||
) {
|
|
||||||
command.append(ch)
|
|
||||||
reprocess = false
|
|
||||||
if (!Character.isLetter(ch) && "<>".indexOf(ch) < 0) {
|
|
||||||
state = State.CMD_ARG
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state = State.CMD_ARG
|
|
||||||
}
|
|
||||||
State.CMD_ARG -> {
|
|
||||||
argument.append(ch)
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE -> {
|
|
||||||
location = StringBuffer()
|
|
||||||
offsetTotal = 0
|
|
||||||
offsetNumber = 0
|
|
||||||
move = false
|
|
||||||
if (ch in '0'..'9') {
|
|
||||||
state = State.RANGE_LINE
|
|
||||||
} else if (ch == '.') {
|
|
||||||
state = State.RANGE_CURRENT
|
|
||||||
} else if (ch == '$') {
|
|
||||||
state = State.RANGE_LAST
|
|
||||||
} else if (ch == '%') {
|
|
||||||
state = State.RANGE_ALL
|
|
||||||
} else if (ch == '\'') {
|
|
||||||
state = State.RANGE_MARK
|
|
||||||
} else if (ch == '+' || ch == '-') {
|
|
||||||
location.append('.')
|
|
||||||
state = State.RANGE_OFFSET
|
|
||||||
} else if (ch == '\\') {
|
|
||||||
location.append(ch)
|
|
||||||
state = State.RANGE_SHORT_PATTERN
|
|
||||||
reprocess = false
|
|
||||||
} else if (ch == ',') {
|
|
||||||
location.append('.')
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
} else if (ch == '/' || ch == '?') {
|
|
||||||
location.append(ch)
|
|
||||||
patternType = ch
|
|
||||||
backCount = 0
|
|
||||||
inBrackets = false
|
|
||||||
state = State.RANGE_PATTERN
|
|
||||||
reprocess = false
|
|
||||||
} else {
|
|
||||||
error = message(Msg.e_badrange, Character.toString(ch))
|
|
||||||
state = State.ERROR
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
State.RANGE_SHORT_PATTERN -> {
|
|
||||||
if (ch == '/' || ch == '?' || ch == '&') {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_PATTERN_MAYBE_DONE
|
|
||||||
} else {
|
|
||||||
error = message(Msg.e_backslash)
|
|
||||||
state = State.ERROR
|
|
||||||
}
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_PATTERN -> // No trailing / or ? required if there is no command so look for newline to tell us we are done
|
|
||||||
if (ch == '\n') {
|
|
||||||
location!!.append(patternType)
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
} else {
|
|
||||||
// We need to skip over [ ] ranges. The ] is valid right after the [ or [^
|
|
||||||
location!!.append(ch)
|
|
||||||
if (ch == '[' && !inBrackets) {
|
|
||||||
inBrackets = true
|
|
||||||
} else if (ch == ']' && inBrackets && !(location[location.length - 2] == '[' ||
|
|
||||||
location.length >= 3 && location.substring(location.length - 3) == "[^]")
|
|
||||||
) {
|
|
||||||
inBrackets = false
|
|
||||||
} else if (ch == '\\') {
|
|
||||||
backCount++
|
|
||||||
} else if (ch == patternType && !inBrackets &&
|
|
||||||
(location[location.length - 2] != '\\' || backCount % 2 == 0)
|
|
||||||
) {
|
|
||||||
state = State.RANGE_PATTERN_MAYBE_DONE
|
|
||||||
}
|
|
||||||
|
|
||||||
// No more backslashes
|
|
||||||
if (ch != '\\') {
|
|
||||||
backCount = 0
|
|
||||||
}
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_PATTERN_MAYBE_DONE -> if (ch == '/' || ch == '?') {
|
|
||||||
// Use a special character to separate pattern for later, easier, parsing
|
|
||||||
location!!.append('\u0000')
|
|
||||||
location.append(ch)
|
|
||||||
patternType = ch
|
|
||||||
backCount = 0
|
|
||||||
inBrackets = false
|
|
||||||
state = State.RANGE_PATTERN
|
|
||||||
reprocess = false
|
|
||||||
} else {
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
}
|
|
||||||
State.RANGE_LINE -> if (ch in '0'..'9') {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
} else {
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
}
|
|
||||||
State.RANGE_CURRENT -> {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_LAST -> {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_ALL -> {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_MARK -> {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_MARK_CHAR
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_MARK_CHAR -> {
|
|
||||||
location!!.append(ch)
|
|
||||||
state = State.RANGE_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_DONE -> {
|
|
||||||
val range = createRange(location.toString(), offsetTotal, move)
|
|
||||||
if (range == null) {
|
|
||||||
error = message(Msg.e_badrange, Character.toString(ch))
|
|
||||||
state = State.ERROR
|
|
||||||
reprocess = false
|
|
||||||
break@loop
|
|
||||||
}
|
|
||||||
ranges.addRange(range)
|
|
||||||
// Could there be more ranges - nope - at end, start command
|
|
||||||
if (ch == ':' || ch == '\n') {
|
|
||||||
state = State.COMMAND
|
|
||||||
reprocess = false
|
|
||||||
} else if (Character.isLetter(ch) || "~<>@=#*&!".indexOf(ch) >= 0 || ch == ' ') {
|
|
||||||
state = State.START
|
|
||||||
} else {
|
|
||||||
state = State.RANGE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
State.RANGE_MAYBE_DONE -> // The range has an offset after it
|
|
||||||
state = if (ch == '+' || ch == '-') {
|
|
||||||
State.RANGE_OFFSET
|
|
||||||
} else if (ch == ',' || ch == ';') {
|
|
||||||
State.RANGE_SEPARATOR
|
|
||||||
} else if (ch in '0'..'9') {
|
|
||||||
State.RANGE_LINE
|
|
||||||
} else {
|
|
||||||
State.RANGE_DONE
|
|
||||||
}
|
|
||||||
State.RANGE_OFFSET -> {
|
|
||||||
// Figure out the sign of the offset and reset the offset value
|
|
||||||
offsetNumber = 0
|
|
||||||
if (ch == '+') {
|
|
||||||
offsetSign = 1
|
|
||||||
} else if (ch == '-') {
|
|
||||||
offsetSign = -1
|
|
||||||
}
|
|
||||||
state = State.RANGE_OFFSET_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.RANGE_OFFSET_MAYBE_DONE -> // We found an offset value
|
|
||||||
state = if (ch in '0'..'9') {
|
|
||||||
State.RANGE_OFFSET_NUM
|
|
||||||
} else {
|
|
||||||
State.RANGE_OFFSET_DONE
|
|
||||||
}
|
|
||||||
State.RANGE_OFFSET_DONE -> {
|
|
||||||
// No number implies a one
|
|
||||||
if (offsetNumber == 0) {
|
|
||||||
offsetNumber = 1
|
|
||||||
}
|
|
||||||
// Update offset total for this range
|
|
||||||
offsetTotal += offsetNumber * offsetSign
|
|
||||||
|
|
||||||
// Another offset
|
|
||||||
state = if (ch == '+' || ch == '-') {
|
|
||||||
State.RANGE_OFFSET
|
|
||||||
} else {
|
|
||||||
State.RANGE_MAYBE_DONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
State.RANGE_OFFSET_NUM -> // Update the value of the current offset
|
|
||||||
if (ch in '0'..'9') {
|
|
||||||
offsetNumber = offsetNumber * 10 + (ch - '0')
|
|
||||||
state = State.RANGE_OFFSET_MAYBE_DONE
|
|
||||||
reprocess = false
|
|
||||||
} else if (ch == '+' || ch == '-') {
|
|
||||||
state = State.RANGE_OFFSET_DONE
|
|
||||||
} else {
|
|
||||||
state = State.RANGE_OFFSET_MAYBE_DONE
|
|
||||||
}
|
|
||||||
State.RANGE_SEPARATOR -> {
|
|
||||||
if (ch == ',') {
|
|
||||||
move = false
|
|
||||||
} else if (ch == ';') {
|
|
||||||
move = true
|
|
||||||
}
|
|
||||||
state = State.RANGE_DONE
|
|
||||||
reprocess = false
|
|
||||||
}
|
|
||||||
State.ERROR -> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Oops - bad command string
|
|
||||||
if (state == State.ERROR) {
|
|
||||||
throw InvalidCommandException(error, cmd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (logger.isDebugEnabled) {
|
|
||||||
logger.debug("ranges = $ranges")
|
|
||||||
logger.debug("command = $command")
|
|
||||||
logger.debug("argument = $argument")
|
|
||||||
}
|
|
||||||
var argumentString = argument.toString()
|
|
||||||
val matcher = TRIM_WHITESPACE.matcher(argumentString)
|
|
||||||
if (matcher.matches()) {
|
|
||||||
argumentString = matcher.group(1)
|
|
||||||
}
|
|
||||||
return ExCommand(ranges, command.toString(), argumentString)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a command handler to the parser */
|
|
||||||
fun addHandler(handlerHolder: ExBeanClass) {
|
|
||||||
// Iterator through each command name alias
|
|
||||||
val names: Array<CommandName> = when {
|
|
||||||
handlerHolder.names != null -> {
|
|
||||||
commands(*handlerHolder.names!!.split(",").toTypedArray())
|
|
||||||
}
|
|
||||||
handlerHolder.instance is ComplicatedNameExCommand -> {
|
|
||||||
(handlerHolder.instance as ComplicatedNameExCommand).names
|
|
||||||
}
|
|
||||||
else -> throw RuntimeException("Cannot create an ex command: $handlerHolder")
|
|
||||||
}
|
|
||||||
for (name in names) {
|
|
||||||
var node = root
|
|
||||||
var text = name.required
|
|
||||||
// Build a tree for each character in the required portion of the command name
|
|
||||||
for (i in 0 until text.length - 1) {
|
|
||||||
var cn = node.getChild(text[i])
|
|
||||||
if (cn == null) {
|
|
||||||
cn = node.addChild(text[i], null)
|
|
||||||
}
|
|
||||||
node = cn
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the last character we need to add the actual handler
|
|
||||||
var cn = node.getChild(text[text.length - 1])
|
|
||||||
if (cn == null) {
|
|
||||||
cn = node.addChild(text[text.length - 1], handlerHolder)
|
|
||||||
} else {
|
|
||||||
cn.commandHandler = handlerHolder
|
|
||||||
}
|
|
||||||
node = cn
|
|
||||||
|
|
||||||
// Now add the handler for each character in the optional portion of the command name
|
|
||||||
text = name.optional
|
|
||||||
for (i in text.indices) {
|
|
||||||
cn = node.getChild(text[i])
|
|
||||||
if (cn == null) {
|
|
||||||
cn = node.addChild(text[i], handlerHolder)
|
|
||||||
} else if (cn.commandHandler == null) {
|
|
||||||
cn.commandHandler = handlerHolder
|
|
||||||
}
|
|
||||||
node = cn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum class State {
|
|
||||||
START, COMMAND,
|
|
||||||
CMD_ARG,
|
|
||||||
RANGE, RANGE_LINE, RANGE_CURRENT, RANGE_LAST, RANGE_MARK, RANGE_MARK_CHAR, RANGE_ALL, RANGE_PATTERN,
|
|
||||||
RANGE_SHORT_PATTERN, RANGE_PATTERN_MAYBE_DONE, RANGE_OFFSET, RANGE_OFFSET_NUM, RANGE_OFFSET_DONE,
|
|
||||||
RANGE_OFFSET_MAYBE_DONE, RANGE_SEPARATOR, RANGE_MAYBE_DONE, RANGE_DONE, ERROR
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.ex
|
|
||||||
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
|
||||||
import com.maddyhome.idea.vim.ex.ranges.Ranges
|
|
||||||
|
|
||||||
class ExCommand(val ranges: Ranges, val command: String, var argument: String) {
|
|
||||||
|
|
||||||
fun getLine(editor: Editor): Int = ranges.getLine(editor)
|
|
||||||
|
|
||||||
fun getLine(editor: Editor, caret: Caret): Int = ranges.getLine(editor, caret)
|
|
||||||
|
|
||||||
fun getCount(editor: Editor, defaultCount: Int, checkCount: Boolean): Int {
|
|
||||||
val count = if (checkCount) countArgument else -1
|
|
||||||
|
|
||||||
val res = ranges.getCount(editor, count)
|
|
||||||
return if (res == -1) defaultCount else res
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCount(editor: Editor, caret: Caret, defaultCount: Int, checkCount: Boolean): Int {
|
|
||||||
val count = ranges.getCount(editor, caret, if (checkCount) countArgument else -1)
|
|
||||||
return if (count == -1) defaultCount else count
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLineRange(editor: Editor): LineRange = ranges.getLineRange(editor, -1)
|
|
||||||
|
|
||||||
fun getLineRange(editor: Editor, caret: Caret): LineRange {
|
|
||||||
return ranges.getLineRange(editor, caret, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTextRange(editor: Editor, checkCount: Boolean): TextRange {
|
|
||||||
val count = if (checkCount) countArgument else -1
|
|
||||||
return ranges.getTextRange(editor, count)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getTextRange(editor: Editor, caret: Caret, checkCount: Boolean): TextRange {
|
|
||||||
return ranges.getTextRange(editor, caret, if (checkCount) countArgument else -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val countArgument: Int
|
|
||||||
get() = argument.toIntOrNull() ?: -1
|
|
||||||
}
|
|
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_FORBIDDEN
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_FORBIDDEN
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
|
|
||||||
class AsciiHandler : CommandHandler.SingleExecution() {
|
|
||||||
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_FORBIDDEN, READ_ONLY)
|
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
VimPlugin.getDigraph().displayAsciiInfo(editor)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_FORBIDDEN
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_FORBIDDEN
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
|
|
||||||
class CmdClearHandler : CommandHandler.SingleExecution() {
|
|
||||||
override val argFlags: CommandHandlerFlags = flags(RANGE_FORBIDDEN, ARGUMENT_FORBIDDEN, READ_ONLY)
|
|
||||||
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
VimPlugin.getCommand().resetAliases()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
|
||||||
import com.maddyhome.idea.vim.ex.ExOutputModel
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
|
||||||
import com.maddyhome.idea.vim.helper.Msg
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class CmdFilterHandler : CommandHandler.SingleExecution() {
|
|
||||||
override val argFlags = flags(RangeFlag.RANGE_OPTIONAL, ArgumentFlag.ARGUMENT_OPTIONAL, Access.WRITABLE)
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
logger.debug("execute")
|
|
||||||
|
|
||||||
var command = cmd.argument
|
|
||||||
if (command.isEmpty()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('!' in command) {
|
|
||||||
val last = VimPlugin.getProcess().lastCommand
|
|
||||||
if (last.isNullOrEmpty()) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message(Msg.e_noprev))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
command = command.replace("!".toRegex(), last)
|
|
||||||
}
|
|
||||||
|
|
||||||
return try {
|
|
||||||
if (cmd.ranges.size() == 0) {
|
|
||||||
// Show command output in a window
|
|
||||||
val commandOutput = VimPlugin.getProcess().executeCommand(command, null)
|
|
||||||
ExOutputModel.getInstance(editor).output(commandOutput)
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
// Filter
|
|
||||||
val range = cmd.getTextRange(editor, false)
|
|
||||||
VimPlugin.getProcess().executeFilter(editor, range, command)
|
|
||||||
}
|
|
||||||
} catch (e: IOException) {
|
|
||||||
throw ExException(e.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val logger = Logger.getInstance(CmdFilterHandler::class.java.name)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.Access.READ_ONLY
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_OPTIONAL
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_REQUIRED
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This handles Ex commands that just specify a range which translates to moving the cursor to the line given by the
|
|
||||||
* range.
|
|
||||||
*/
|
|
||||||
class GotoLineHandler : CommandHandler.ForEachCaret() {
|
|
||||||
override val argFlags: CommandHandlerFlags = flags(RANGE_REQUIRED, ARGUMENT_OPTIONAL, READ_ONLY)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves the cursor to the line entered by the user
|
|
||||||
*
|
|
||||||
* @param editor The editor to perform the action in
|
|
||||||
* @param caret The caret to perform the action on
|
|
||||||
* @param context The data context
|
|
||||||
* @param cmd The complete Ex command including range, command, and arguments
|
|
||||||
* @return True if able to perform the command, false if not
|
|
||||||
*/
|
|
||||||
override fun execute(editor: Editor, caret: Caret, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
val line = min(cmd.getLine(editor, caret), EditorHelper.getLineCount(editor) - 1)
|
|
||||||
|
|
||||||
if (line >= 0) {
|
|
||||||
MotionGroup.moveCaret(editor, caret, VimPlugin.getMotion().moveCaretToLineStartSkipLeading(editor, line))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
MotionGroup.moveCaret(editor, caret, 0)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptCommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptGlobalEnvironment
|
|
||||||
import com.maddyhome.idea.vim.ex.vimscript.VimScriptParser
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author vlan
|
|
||||||
*/
|
|
||||||
class LetHandler : CommandHandler.SingleExecution(), VimScriptCommandHandler {
|
|
||||||
override val argFlags = flags(RangeFlag.RANGE_FORBIDDEN, ArgumentFlag.ARGUMENT_OPTIONAL, Access.READ_ONLY)
|
|
||||||
|
|
||||||
@Throws(ExException::class)
|
|
||||||
override fun execute(editor: Editor, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
execute(cmd)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws
|
|
||||||
override fun execute(cmd: ExCommand) {
|
|
||||||
val argument = cmd.argument
|
|
||||||
if (argument.trim().isEmpty()) {
|
|
||||||
showVariables()
|
|
||||||
} else {
|
|
||||||
val matcher = SIMPLE_ASSIGNMENT.matcher(argument)
|
|
||||||
if (matcher.matches()) {
|
|
||||||
val name = matcher.group(1)
|
|
||||||
// TODO: Check that 'name' is global
|
|
||||||
val expression = matcher.group(2)
|
|
||||||
val env = VimScriptGlobalEnvironment.getInstance()
|
|
||||||
val globals = env.variables
|
|
||||||
val value = VimScriptParser.evaluate(expression, globals)
|
|
||||||
globals[name] = value
|
|
||||||
} else {
|
|
||||||
throw ExException("Only simple '=' assignments are supported in 'let' expressions")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ExException::class)
|
|
||||||
private fun showVariables() {
|
|
||||||
throw ExException("'let' without arguments is not supported yet")
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val SIMPLE_ASSIGNMENT = Pattern.compile("((?:[gswtblav]:)?[A-Za-z_][A-Za-z_0-9]*)[ \\t]*=[ \\t]*(.*)")
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.Access.WRITABLE
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_OPTIONAL
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_OPTIONAL
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandName
|
|
||||||
import com.maddyhome.idea.vim.ex.ComplicatedNameExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.commands
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
|
|
||||||
class ShiftLeftHandler : CommandHandler.ForEachCaret(), ComplicatedNameExCommand {
|
|
||||||
override val names: Array<CommandName> = commands("<[${"<".repeat(31)}]")
|
|
||||||
override val argFlags: CommandHandlerFlags = flags(RANGE_OPTIONAL, ARGUMENT_OPTIONAL, WRITABLE)
|
|
||||||
|
|
||||||
override fun execute(editor: Editor, caret: Caret, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
val range = cmd.getTextRange(editor, caret, true)
|
|
||||||
val endOffsets = range.endOffsets.map { it - 1 }.toIntArray()
|
|
||||||
VimPlugin.getChange().indentRange(
|
|
||||||
editor, caret, context,
|
|
||||||
TextRange(range.startOffsets, endOffsets),
|
|
||||||
cmd.command.length, -1
|
|
||||||
)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.ex.handler
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.Access.WRITABLE
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.ArgumentFlag.ARGUMENT_OPTIONAL
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandler.RangeFlag.RANGE_OPTIONAL
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandHandlerFlags
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandName
|
|
||||||
import com.maddyhome.idea.vim.ex.ComplicatedNameExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.ExCommand
|
|
||||||
import com.maddyhome.idea.vim.ex.commands
|
|
||||||
import com.maddyhome.idea.vim.ex.flags
|
|
||||||
|
|
||||||
class ShiftRightHandler : CommandHandler.ForEachCaret(), ComplicatedNameExCommand {
|
|
||||||
override val names: Array<CommandName> = commands(">[${">".repeat(31)}]")
|
|
||||||
override val argFlags: CommandHandlerFlags = flags(RANGE_OPTIONAL, ARGUMENT_OPTIONAL, WRITABLE)
|
|
||||||
|
|
||||||
override fun execute(editor: Editor, caret: Caret, context: DataContext, cmd: ExCommand): Boolean {
|
|
||||||
val range = cmd.getTextRange(editor, caret, true)
|
|
||||||
val endOffsets = range.endOffsets.map { it - 1 }.toIntArray()
|
|
||||||
VimPlugin.getChange().indentRange(
|
|
||||||
editor, caret, context,
|
|
||||||
TextRange(range.startOffsets, endOffsets),
|
|
||||||
cmd.command.length, 1
|
|
||||||
)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.maddyhome.idea.vim.ex.vimscript
|
|
||||||
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandParser
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException
|
|
||||||
import com.maddyhome.idea.vim.ui.VimRcFileState
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
import java.nio.file.Paths
|
|
||||||
import java.util.regex.Matcher
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author vlan
|
|
||||||
*/
|
|
||||||
object VimScriptParser {
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val VIMRC_FILE_NAME = "ideavimrc"
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private val HOME_VIMRC_PATHS = arrayOf(".$VIMRC_FILE_NAME", "_$VIMRC_FILE_NAME")
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private val XDG_VIMRC_PATH = "ideavim" + File.separator + VIMRC_FILE_NAME
|
|
||||||
private val DOUBLE_QUOTED_STRING = Pattern.compile("\"([^\"]*)\"")
|
|
||||||
private val SINGLE_QUOTED_STRING = Pattern.compile("'([^']*)'")
|
|
||||||
private val REFERENCE_EXPR = Pattern.compile("([A-Za-z_][A-Za-z_0-9]*)")
|
|
||||||
private val DEC_NUMBER = Pattern.compile("(\\d+)")
|
|
||||||
|
|
||||||
// This is a pattern used in ideavimrc parsing for a long time. It removes all trailing/leading spaced and blank lines
|
|
||||||
private val EOL_SPLIT_PATTERN = Pattern.compile(" *(\r\n|\n)+ *")
|
|
||||||
|
|
||||||
var executingVimScript = false
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun findIdeaVimRc(): File? {
|
|
||||||
val homeDirName = System.getProperty("user.home")
|
|
||||||
// Check whether file exists in home dir
|
|
||||||
if (homeDirName != null) {
|
|
||||||
for (fileName in HOME_VIMRC_PATHS) {
|
|
||||||
val file = File(homeDirName, fileName)
|
|
||||||
if (file.exists()) {
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check in XDG config directory
|
|
||||||
val xdgConfigHomeProperty = System.getenv("XDG_CONFIG_HOME")
|
|
||||||
val xdgConfig = if (xdgConfigHomeProperty == null || xdgConfigHomeProperty == "") {
|
|
||||||
if (homeDirName != null) Paths.get(homeDirName, ".config", XDG_VIMRC_PATH).toFile() else null
|
|
||||||
} else {
|
|
||||||
File(xdgConfigHomeProperty, XDG_VIMRC_PATH)
|
|
||||||
}
|
|
||||||
return if (xdgConfig != null && xdgConfig.exists()) xdgConfig else null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findOrCreateIdeaVimRc(): File? {
|
|
||||||
val found = findIdeaVimRc()
|
|
||||||
if (found != null) return found
|
|
||||||
|
|
||||||
val homeDirName = System.getProperty("user.home")
|
|
||||||
if (homeDirName != null) {
|
|
||||||
for (fileName in HOME_VIMRC_PATHS) {
|
|
||||||
try {
|
|
||||||
val file = File(homeDirName, fileName)
|
|
||||||
file.createNewFile()
|
|
||||||
VimRcFileState.filePath = file.absolutePath
|
|
||||||
return file
|
|
||||||
} catch (ignored: IOException) {
|
|
||||||
// Try to create one of two files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun executeFile(file: File): List<String> {
|
|
||||||
val data = try {
|
|
||||||
readFile(file)
|
|
||||||
} catch (ignored: IOException) {
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
executeText(data)
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
fun executeText(vararg text: String) {
|
|
||||||
executeText(listOf(*text))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun executeText(text: List<String>) {
|
|
||||||
for (line in text) {
|
|
||||||
// TODO: Build a proper parse tree for a VimL file instead of ignoring potentially nested lines (VIM-669)
|
|
||||||
if (line.startsWith(" ") || line.startsWith("\t")) continue
|
|
||||||
|
|
||||||
val lineToExecute = if (line.startsWith(":")) line.substring(1) else line
|
|
||||||
try {
|
|
||||||
val command = CommandParser.parse(lineToExecute)
|
|
||||||
val commandHandler = CommandParser.getCommandHandler(command)
|
|
||||||
if (commandHandler is VimScriptCommandHandler) {
|
|
||||||
commandHandler.execute(command)
|
|
||||||
}
|
|
||||||
} catch (ignored: ExException) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ExException::class)
|
|
||||||
fun evaluate(expression: String, globals: Map<String?, Any?>): Any {
|
|
||||||
// This evaluator is very basic, no proper parsing whatsoever. It is here as the very first step necessary to
|
|
||||||
// support mapleader, VIM-650. See also VIM-669.
|
|
||||||
var m: Matcher = DOUBLE_QUOTED_STRING.matcher(expression)
|
|
||||||
if (m.matches()) return m.group(1)
|
|
||||||
|
|
||||||
m = SINGLE_QUOTED_STRING.matcher(expression)
|
|
||||||
if (m.matches()) return m.group(1)
|
|
||||||
|
|
||||||
m = REFERENCE_EXPR.matcher(expression)
|
|
||||||
if (m.matches()) {
|
|
||||||
val name = m.group(1)
|
|
||||||
val value = globals[name]
|
|
||||||
return value ?: throw ExException("Undefined variable: $name")
|
|
||||||
}
|
|
||||||
|
|
||||||
m = DEC_NUMBER.matcher(expression)
|
|
||||||
if (m.matches()) return m.group(1).toInt()
|
|
||||||
|
|
||||||
throw ExException("Invalid expression: $expression")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ExException::class)
|
|
||||||
fun expressionToString(value: Any): String {
|
|
||||||
// TODO: Return meaningful value representations
|
|
||||||
return when (value) {
|
|
||||||
is String -> value
|
|
||||||
is Int -> value.toString()
|
|
||||||
else -> throw ExException("Cannot convert '$value' to string")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(IOException::class)
|
|
||||||
fun readFile(file: File): List<String> {
|
|
||||||
val lines = ArrayList<String>()
|
|
||||||
file.forEachLine { line -> lineProcessor(line, lines) }
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
fun readText(data: CharSequence): List<String> {
|
|
||||||
val lines = ArrayList<String>()
|
|
||||||
EOL_SPLIT_PATTERN.split(data).forEach { line -> lineProcessor(line, lines) }
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
fun lineProcessor(line: String, lines: ArrayList<String>) {
|
|
||||||
val trimmedLine = line.trim()
|
|
||||||
if (trimmedLine.isBlank()) return
|
|
||||||
lines += trimmedLine
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,287 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.extension.multiplecursors
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.editor.VisualPosition
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags
|
|
||||||
import com.maddyhome.idea.vim.command.MappingMode
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtension
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putExtensionHandlerMapping
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMappingIfMissing
|
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler
|
|
||||||
import com.maddyhome.idea.vim.group.MotionGroup
|
|
||||||
import com.maddyhome.idea.vim.group.visual.vimSetSelection
|
|
||||||
import com.maddyhome.idea.vim.helper.Direction
|
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
|
||||||
import com.maddyhome.idea.vim.helper.MessageHelper
|
|
||||||
import com.maddyhome.idea.vim.helper.SearchHelper.findWordUnderCursor
|
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper.parseKeys
|
|
||||||
import com.maddyhome.idea.vim.helper.endOffsetInclusive
|
|
||||||
import com.maddyhome.idea.vim.helper.exitVisualMode
|
|
||||||
import com.maddyhome.idea.vim.helper.inVisualMode
|
|
||||||
import com.maddyhome.idea.vim.option.OptionsManager
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import java.lang.Integer.min
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val NEXT_WHOLE_OCCURRENCE = "<Plug>NextWholeOccurrence"
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val NEXT_OCCURRENCE = "<Plug>NextOccurrence"
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val SKIP_OCCURRENCE = "<Plug>SkipOccurrence"
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val REMOVE_OCCURRENCE = "<Plug>RemoveOccurrence"
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val ALL_WHOLE_OCCURRENCES = "<Plug>AllWholeOccurrences"
|
|
||||||
|
|
||||||
// [VERSION UPDATE] 203+ Annotation should be replaced with @NlsSafe
|
|
||||||
@NonNls
|
|
||||||
private const val ALL_OCCURRENCES = "<Plug>AllOccurrences"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Port of vim-multiple-cursors.
|
|
||||||
*
|
|
||||||
* See https://github.com/terryma/vim-multiple-cursors
|
|
||||||
* */
|
|
||||||
class VimMultipleCursorsExtension : VimExtension {
|
|
||||||
|
|
||||||
override fun getName() = "multiple-cursors"
|
|
||||||
|
|
||||||
override fun init() {
|
|
||||||
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(NEXT_WHOLE_OCCURRENCE), owner, NextOccurrenceHandler(), false)
|
|
||||||
putExtensionHandlerMapping(
|
|
||||||
MappingMode.NXO,
|
|
||||||
parseKeys(NEXT_OCCURRENCE),
|
|
||||||
owner,
|
|
||||||
NextOccurrenceHandler(whole = false),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
putExtensionHandlerMapping(MappingMode.NXO, parseKeys(ALL_WHOLE_OCCURRENCES), owner, AllOccurrencesHandler(), false)
|
|
||||||
putExtensionHandlerMapping(
|
|
||||||
MappingMode.NXO,
|
|
||||||
parseKeys(ALL_OCCURRENCES),
|
|
||||||
owner,
|
|
||||||
AllOccurrencesHandler(whole = false),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
putExtensionHandlerMapping(MappingMode.X, parseKeys(SKIP_OCCURRENCE), owner, SkipOccurrenceHandler(), false)
|
|
||||||
putExtensionHandlerMapping(MappingMode.X, parseKeys(REMOVE_OCCURRENCE), owner, RemoveOccurrenceHandler(), false)
|
|
||||||
|
|
||||||
putKeyMappingIfMissing(MappingMode.NXO, parseKeys("<A-n>"), owner, parseKeys(NEXT_WHOLE_OCCURRENCE), true)
|
|
||||||
putKeyMappingIfMissing(MappingMode.NXO, parseKeys("g<A-n>"), owner, parseKeys(NEXT_OCCURRENCE), true)
|
|
||||||
putKeyMappingIfMissing(MappingMode.X, parseKeys("<A-x>"), owner, parseKeys(SKIP_OCCURRENCE), true)
|
|
||||||
putKeyMappingIfMissing(MappingMode.X, parseKeys("<A-p>"), owner, parseKeys(REMOVE_OCCURRENCE), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class WriteActionHandler : VimExtensionHandler {
|
|
||||||
override fun execute(editor: Editor, context: DataContext) {
|
|
||||||
ApplicationManager.getApplication().runWriteAction {
|
|
||||||
executeInWriteAction(editor, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun executeInWriteAction(editor: Editor, context: DataContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class NextOccurrenceHandler(val whole: Boolean = true) : WriteActionHandler() {
|
|
||||||
override fun executeInWriteAction(editor: Editor, context: DataContext) {
|
|
||||||
val caretModel = editor.caretModel
|
|
||||||
val patternComparator =
|
|
||||||
if (OptionsManager.ignorecase.isSet) String.CASE_INSENSITIVE_ORDER else Comparator(String::compareTo)
|
|
||||||
|
|
||||||
if (!editor.inVisualMode) {
|
|
||||||
if (caretModel.caretCount > 1) return
|
|
||||||
|
|
||||||
val caret = caretModel.primaryCaret
|
|
||||||
val range = findWordUnderCursor(editor, caret) ?: return
|
|
||||||
if (range.startOffset > caret.offset) return
|
|
||||||
|
|
||||||
val nextOffset = findNextOccurrence(editor, caret, range, whole)
|
|
||||||
if (nextOffset == caret.selectionStart) VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
|
||||||
} else {
|
|
||||||
val newPositions = arrayListOf<VisualPosition>()
|
|
||||||
val patterns = sortedSetOf(patternComparator)
|
|
||||||
for (caret in caretModel.allCarets) {
|
|
||||||
val selectedText = caret.selectedText ?: return
|
|
||||||
patterns += selectedText
|
|
||||||
|
|
||||||
val lines = selectedText.count { it == '\n' }
|
|
||||||
if (lines > 0) {
|
|
||||||
val selectionStart = min(caret.selectionStart, caret.selectionEnd)
|
|
||||||
val startPosition = editor.offsetToVisualPosition(selectionStart)
|
|
||||||
for (line in startPosition.line + 1..startPosition.line + lines) {
|
|
||||||
newPositions += VisualPosition(line, startPosition.column)
|
|
||||||
}
|
|
||||||
MotionGroup.moveCaret(editor, caret, selectionStart)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (newPositions.size > 0) {
|
|
||||||
editor.exitVisualMode()
|
|
||||||
newPositions.forEach { editor.caretModel.addCaret(it) ?: return }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (patterns.size > 1) return
|
|
||||||
|
|
||||||
val primaryCaret = editor.caretModel.primaryCaret
|
|
||||||
val nextOffset = VimPlugin.getSearch().searchNextFromOffset(editor, primaryCaret.offset + 1, 1)
|
|
||||||
val pattern = patterns.first()
|
|
||||||
if (nextOffset == -1 || patternComparator.compare(
|
|
||||||
EditorHelper.getText(
|
|
||||||
editor,
|
|
||||||
nextOffset,
|
|
||||||
nextOffset + pattern.length
|
|
||||||
), pattern
|
|
||||||
) != 0
|
|
||||||
) {
|
|
||||||
if (caretModel.caretCount > 1) return
|
|
||||||
|
|
||||||
val newNextOffset =
|
|
||||||
VimPlugin.getSearch().search(editor, pattern, 1, EnumSet.of(CommandFlags.FLAG_SEARCH_FWD), false)
|
|
||||||
|
|
||||||
if (newNextOffset != -1) {
|
|
||||||
val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(newNextOffset)) ?: return
|
|
||||||
selectWord(caret, pattern, newNextOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
caretModel.allCarets.forEach {
|
|
||||||
if (it.selectionStart == nextOffset) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val caret = editor.caretModel.addCaret(editor.offsetToVisualPosition(nextOffset)) ?: return
|
|
||||||
selectWord(caret, pattern, nextOffset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class AllOccurrencesHandler(val whole: Boolean = true) : WriteActionHandler() {
|
|
||||||
override fun executeInWriteAction(editor: Editor, context: DataContext) {
|
|
||||||
val caretModel = editor.caretModel
|
|
||||||
if (caretModel.caretCount > 1) return
|
|
||||||
|
|
||||||
val primaryCaret = caretModel.primaryCaret
|
|
||||||
var nextOffset = if (editor.inVisualMode) {
|
|
||||||
val selectedText = primaryCaret.selectedText ?: return
|
|
||||||
val nextOffset =
|
|
||||||
VimPlugin.getSearch().search(editor, selectedText, 1, EnumSet.of(CommandFlags.FLAG_SEARCH_FWD), false)
|
|
||||||
nextOffset
|
|
||||||
} else {
|
|
||||||
val range = findWordUnderCursor(editor, primaryCaret) ?: return
|
|
||||||
if (range.startOffset > primaryCaret.offset) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
findNextOccurrence(editor, primaryCaret, range, whole)
|
|
||||||
}
|
|
||||||
|
|
||||||
val firstOffset = primaryCaret.selectionStart
|
|
||||||
val newPositions = arrayListOf(nextOffset, firstOffset)
|
|
||||||
while (nextOffset != firstOffset) {
|
|
||||||
nextOffset = VimPlugin.getSearch().searchNextFromOffset(editor, nextOffset + 1, 1)
|
|
||||||
newPositions += nextOffset
|
|
||||||
}
|
|
||||||
|
|
||||||
val pattern = primaryCaret.selectedText ?: return
|
|
||||||
newPositions.sorted().forEach {
|
|
||||||
val caret = caretModel.addCaret(editor.offsetToVisualPosition(it)) ?: return
|
|
||||||
selectWord(caret, pattern, it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class SkipOccurrenceHandler : WriteActionHandler() {
|
|
||||||
override fun executeInWriteAction(editor: Editor, context: DataContext) {
|
|
||||||
val caret = editor.caretModel.primaryCaret
|
|
||||||
val selectedText = caret.selectedText ?: return
|
|
||||||
|
|
||||||
val nextOffset = tryFindNextOccurrence(editor, caret, selectedText)
|
|
||||||
if (nextOffset == -1) return
|
|
||||||
|
|
||||||
editor.caretModel.allCarets.forEach {
|
|
||||||
if (it.selectionStart == nextOffset) {
|
|
||||||
VimPlugin.showMessage(MessageHelper.message("message.no.more.matches"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val newCaret = editor.caretModel.addCaret(editor.offsetToVisualPosition(nextOffset)) ?: return
|
|
||||||
selectWord(newCaret, selectedText, nextOffset)
|
|
||||||
editor.caretModel.removeCaret(caret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class RemoveOccurrenceHandler : WriteActionHandler() {
|
|
||||||
override fun executeInWriteAction(editor: Editor, context: DataContext) {
|
|
||||||
val caret = editor.caretModel.primaryCaret
|
|
||||||
val selectedText = caret.selectedText ?: return
|
|
||||||
|
|
||||||
if (tryFindNextOccurrence(editor, caret, selectedText) == -1) return
|
|
||||||
|
|
||||||
if (!editor.caretModel.removeCaret(caret)) {
|
|
||||||
editor.exitVisualMode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun selectWord(caret: Caret, pattern: String, offset: Int) {
|
|
||||||
if (pattern.isEmpty()) return
|
|
||||||
caret.vimSetSelection(offset, offset + pattern.length - 1, true)
|
|
||||||
if (caret == caret.editor.caretModel.primaryCaret) MotionGroup.scrollCaretIntoView(caret.editor)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findNextOccurrence(editor: Editor, caret: Caret, range: TextRange, whole: Boolean): Int {
|
|
||||||
VimPlugin.getVisualMotion().setVisualMode(editor)
|
|
||||||
val wordRange = VimPlugin.getMotion().getWordRange(editor, caret, 1, false, false)
|
|
||||||
caret.vimSetSelection(wordRange.startOffset, wordRange.endOffsetInclusive, true)
|
|
||||||
|
|
||||||
val offset = VimPlugin.getSearch().searchWord(editor, caret, 1, whole, Direction.FORWARDS)
|
|
||||||
MotionGroup.moveCaret(editor, caret, range.endOffset - 1)
|
|
||||||
|
|
||||||
return offset
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryFindNextOccurrence(editor: Editor, caret: Caret, pattern: String): Int {
|
|
||||||
val nextOffset = VimPlugin.getSearch().searchNextFromOffset(editor, caret.offset + 1, 1)
|
|
||||||
if (nextOffset == -1 || EditorHelper.getText(editor, nextOffset, nextOffset + pattern.length) != pattern) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
return nextOffset
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.group;
|
|
||||||
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext;
|
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
|
||||||
import com.intellij.util.text.CharSequenceReader;
|
|
||||||
import com.maddyhome.idea.vim.KeyHandler;
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin;
|
|
||||||
import com.maddyhome.idea.vim.command.Command;
|
|
||||||
import com.maddyhome.idea.vim.command.CommandFlags;
|
|
||||||
import com.maddyhome.idea.vim.command.CommandState;
|
|
||||||
import com.maddyhome.idea.vim.common.TextRange;
|
|
||||||
import com.maddyhome.idea.vim.ex.CommandParser;
|
|
||||||
import com.maddyhome.idea.vim.ex.ExException;
|
|
||||||
import com.maddyhome.idea.vim.helper.UiHelper;
|
|
||||||
import com.maddyhome.idea.vim.ui.ex.ExEntryPanel;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
|
|
||||||
|
|
||||||
public class ProcessGroup {
|
|
||||||
public String getLastCommand() {
|
|
||||||
return lastCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startSearchCommand(@NotNull Editor editor, DataContext context, int count, char leader) {
|
|
||||||
if (editor.isOneLineMode()) // Don't allow searching in one line editors
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String initText = "";
|
|
||||||
String label = String.valueOf(leader);
|
|
||||||
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
panel.activate(editor, context, label, initText, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isForwardSearch() {
|
|
||||||
return ExEntryPanel.getInstance().getLabel().equals("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull String endSearchCommand(final @NotNull Editor editor) {
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
panel.deactivate(true);
|
|
||||||
|
|
||||||
return panel.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startExCommand(@NotNull Editor editor, DataContext context, @NotNull Command cmd) {
|
|
||||||
// Don't allow ex commands in one line editors
|
|
||||||
if (editor.isOneLineMode()) return;
|
|
||||||
|
|
||||||
String initText = getRange(editor, cmd);
|
|
||||||
CommandState.getInstance(editor).pushModes(CommandState.Mode.CMD_LINE, CommandState.SubMode.NONE);
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
panel.activate(editor, context, ":", initText, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean processExKey(Editor editor, @NotNull KeyStroke stroke) {
|
|
||||||
// This will only get called if somehow the key focus ended up in the editor while the ex entry window
|
|
||||||
// is open. So I'll put focus back in the editor and process the key.
|
|
||||||
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
if (panel.isActive()) {
|
|
||||||
UiHelper.requestFocus(panel.getEntry());
|
|
||||||
panel.handleKey(stroke);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CommandState.getInstance(editor).popModes();
|
|
||||||
KeyHandler.getInstance().reset(editor);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean processExEntry(final @NotNull Editor editor, final @NotNull DataContext context) {
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
panel.deactivate(true);
|
|
||||||
boolean res = true;
|
|
||||||
try {
|
|
||||||
CommandState.getInstance(editor).popModes();
|
|
||||||
logger.debug("processing command");
|
|
||||||
final String text = panel.getText();
|
|
||||||
if (logger.isDebugEnabled()) logger.debug("swing=" + SwingUtilities.isEventDispatchThread());
|
|
||||||
if (panel.getLabel().equals(":")) {
|
|
||||||
CommandParser.INSTANCE.processCommand(editor, context, text, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// FIXME looks like this branch gets never executed
|
|
||||||
// Search is handled through SearchEntry(Fwd|Rev)Action waiting for an argument type of EX_STRING. Once ex entry
|
|
||||||
// is complete, ProcessExEntryAction should be invoked which would invoke this method. However, keyHandler
|
|
||||||
// massages the Command stack, ignores ProcessExEntryAction, passes the ex content as a string argument to
|
|
||||||
// the previous SearchEntry(Fwd|Rev)Action and invokes it. This works better because the argument text is saved
|
|
||||||
// for repeats, and any leading operators are also executed (e.g. "d/foo")
|
|
||||||
int pos = VimPlugin.getSearch().search(editor, text, panel.getCount(),
|
|
||||||
panel.getLabel().equals("/")
|
|
||||||
? EnumSet.of(CommandFlags.FLAG_SEARCH_FWD)
|
|
||||||
: EnumSet.of(CommandFlags.FLAG_SEARCH_REV), true);
|
|
||||||
if (pos == -1) {
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ExException e) {
|
|
||||||
VimPlugin.showMessage(e.getMessage());
|
|
||||||
VimPlugin.indicateError();
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
catch (Exception bad) {
|
|
||||||
ProcessGroup.logger.error(bad);
|
|
||||||
VimPlugin.indicateError();
|
|
||||||
res = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelExEntry(final @NotNull Editor editor, boolean resetCaret) {
|
|
||||||
CommandState.getInstance(editor).popModes();
|
|
||||||
KeyHandler.getInstance().reset(editor);
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
panel.deactivate(true, resetCaret);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startFilterCommand(@NotNull Editor editor, DataContext context, @NotNull Command cmd) {
|
|
||||||
String initText = getRange(editor, cmd) + "!";
|
|
||||||
CommandState.getInstance(editor).pushModes(CommandState.Mode.CMD_LINE, CommandState.SubMode.NONE);
|
|
||||||
ExEntryPanel panel = ExEntryPanel.getInstance();
|
|
||||||
panel.activate(editor, context, ":", initText, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NotNull String getRange(Editor editor, @NotNull Command cmd) {
|
|
||||||
String initText = "";
|
|
||||||
if (CommandState.getInstance(editor).getMode() == CommandState.Mode.VISUAL) {
|
|
||||||
initText = "'<,'>";
|
|
||||||
}
|
|
||||||
else if (cmd.getRawCount() > 0) {
|
|
||||||
if (cmd.getCount() == 1) {
|
|
||||||
initText = ".";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
initText = ".,.+" + (cmd.getCount() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return initText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean executeFilter(@NotNull Editor editor, @NotNull TextRange range,
|
|
||||||
@NotNull String command) throws IOException {
|
|
||||||
final CharSequence charsSequence = editor.getDocument().getCharsSequence();
|
|
||||||
final int startOffset = range.getStartOffset();
|
|
||||||
final int endOffset = range.getEndOffset();
|
|
||||||
final String output = executeCommand(command, charsSequence.subSequence(startOffset, endOffset));
|
|
||||||
editor.getDocument().replaceString(startOffset, endOffset, output);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull String executeCommand(@NotNull String command, @Nullable CharSequence input) throws IOException {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("command=" + command);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Process process = Runtime.getRuntime().exec(command);
|
|
||||||
|
|
||||||
if (input != null) {
|
|
||||||
final BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
|
|
||||||
copy(new CharSequenceReader(input), outputWriter);
|
|
||||||
outputWriter.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
final BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
||||||
final StringWriter writer = new StringWriter();
|
|
||||||
copy(inputReader, writer);
|
|
||||||
writer.close();
|
|
||||||
|
|
||||||
lastCommand = command;
|
|
||||||
return writer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copy(@NotNull Reader from, @NotNull Writer to) throws IOException {
|
|
||||||
char[] buf = new char[2048];
|
|
||||||
int cnt;
|
|
||||||
while ((cnt = from.read(buf)) != -1) {
|
|
||||||
to.write(buf, 0, cnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String lastCommand;
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getInstance(ProcessGroup.class.getName());
|
|
||||||
}
|
|
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.key;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NonNls;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author vlan
|
|
||||||
*/
|
|
||||||
public enum ShortcutOwner {
|
|
||||||
UNDEFINED("undefined", "Undefined"),
|
|
||||||
IDE(Constants.IDE_STRING, "IDE"),
|
|
||||||
VIM(Constants.VIM_STRING, "Vim");
|
|
||||||
|
|
||||||
private final @NotNull @NonNls String name;
|
|
||||||
private final @NotNull @NonNls String title;
|
|
||||||
|
|
||||||
ShortcutOwner(@NotNull @NonNls String name, @NotNull @NonNls String title) {
|
|
||||||
this.name = name;
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NotNull ShortcutOwner fromString(@NotNull String s) {
|
|
||||||
if (Constants.IDE_STRING.equals(s)) {
|
|
||||||
return IDE;
|
|
||||||
}
|
|
||||||
else if (Constants.VIM_STRING.equals(s)) {
|
|
||||||
return VIM;
|
|
||||||
}
|
|
||||||
return UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String toString() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Constants {
|
|
||||||
@NonNls private static final String IDE_STRING = "ide";
|
|
||||||
@NonNls private static final String VIM_STRING = "vim";
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,299 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.listener
|
|
||||||
|
|
||||||
import com.intellij.codeInsight.lookup.LookupEvent
|
|
||||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
|
||||||
import com.intellij.codeInsight.template.Template
|
|
||||||
import com.intellij.codeInsight.template.TemplateEditingAdapter
|
|
||||||
import com.intellij.codeInsight.template.TemplateManagerListener
|
|
||||||
import com.intellij.codeInsight.template.impl.TemplateState
|
|
||||||
import com.intellij.find.FindModelListener
|
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
|
||||||
import com.intellij.openapi.actionSystem.AnAction
|
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
|
||||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
|
||||||
import com.intellij.openapi.actionSystem.DataContext
|
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
|
||||||
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
|
||||||
import com.intellij.openapi.editor.Caret
|
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.editor.actionSystem.EditorActionManager
|
|
||||||
import com.intellij.openapi.editor.event.CaretEvent
|
|
||||||
import com.intellij.openapi.editor.event.CaretListener
|
|
||||||
import com.intellij.openapi.project.DumbAwareToggleAction
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.Key
|
|
||||||
import com.intellij.util.PlatformUtils
|
|
||||||
import com.maddyhome.idea.vim.EventFacade
|
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
|
||||||
import com.maddyhome.idea.vim.command.CommandState
|
|
||||||
import com.maddyhome.idea.vim.group.visual.IdeaSelectionControl
|
|
||||||
import com.maddyhome.idea.vim.group.visual.moveCaretOneCharLeftFromSelectionEnd
|
|
||||||
import com.maddyhome.idea.vim.helper.EditorDataContext
|
|
||||||
import com.maddyhome.idea.vim.helper.commandState
|
|
||||||
import com.maddyhome.idea.vim.helper.fileSize
|
|
||||||
import com.maddyhome.idea.vim.helper.getTopLevelEditor
|
|
||||||
import com.maddyhome.idea.vim.helper.inNormalMode
|
|
||||||
import com.maddyhome.idea.vim.option.IdeaRefactorMode
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import org.jetbrains.annotations.NotNull
|
|
||||||
import java.beans.PropertyChangeEvent
|
|
||||||
import java.beans.PropertyChangeListener
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Alex Plate
|
|
||||||
*/
|
|
||||||
object IdeaSpecifics {
|
|
||||||
fun addIdeaSpecificsListeners(project: Project) {
|
|
||||||
EventFacade.getInstance().registerLookupListener(project, LookupListener)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeIdeaSpecificsListeners(project: Project) {
|
|
||||||
EventFacade.getInstance().removeLookupListener(project, LookupListener)
|
|
||||||
}
|
|
||||||
|
|
||||||
class VimActionListener : AnActionListener {
|
|
||||||
@NonNls
|
|
||||||
private val surrounderItems = listOf("if", "if / else", "for")
|
|
||||||
private val surrounderAction = "com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler\$InvokeSurrounderAction"
|
|
||||||
private var editor: Editor? = null
|
|
||||||
override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
|
||||||
if (!VimPlugin.isEnabled()) return
|
|
||||||
|
|
||||||
val hostEditor = dataContext.getData(CommonDataKeys.HOST_EDITOR)
|
|
||||||
if (hostEditor != null) {
|
|
||||||
editor = hostEditor
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FindActionId.enabled) {
|
|
||||||
val id: String? = ActionManager.getInstance().getId(action)
|
|
||||||
VimPlugin.getNotifications(dataContext.getData(CommonDataKeys.PROJECT)).notifyActionId(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun afterActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
|
||||||
if (!VimPlugin.isEnabled()) return
|
|
||||||
|
|
||||||
//region Extend Selection for Rider
|
|
||||||
if (PlatformUtils.isRider()) {
|
|
||||||
when (ActionManager.getInstance().getId(action)) {
|
|
||||||
IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET, IdeActions.ACTION_EDITOR_UNSELECT_WORD_AT_CARET -> {
|
|
||||||
// Rider moves caret to the end of selection
|
|
||||||
editor?.caretModel?.addCaretListener(object : CaretListener {
|
|
||||||
override fun caretPositionChanged(event: CaretEvent) {
|
|
||||||
val eventEditor = event.editor.getTopLevelEditor()
|
|
||||||
val predictedMode = IdeaSelectionControl.predictMode(eventEditor, VimListenerManager.SelectionSource.OTHER)
|
|
||||||
moveCaretOneCharLeftFromSelectionEnd(eventEditor, predictedMode)
|
|
||||||
eventEditor.caretModel.removeCaretListener(this)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region Enter insert mode after surround with if
|
|
||||||
if (surrounderAction == action.javaClass.name && surrounderItems.any { action.templatePresentation.text.endsWith(it) }) {
|
|
||||||
editor?.let {
|
|
||||||
val commandState = it.commandState
|
|
||||||
while (commandState.mode != CommandState.Mode.COMMAND) {
|
|
||||||
commandState.popModes()
|
|
||||||
}
|
|
||||||
VimPlugin.getChange().insertBeforeCursor(it, dataContext)
|
|
||||||
KeyHandler.getInstance().reset(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
editor = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//region Enter insert mode for surround templates without selection
|
|
||||||
class VimTemplateManagerListener : TemplateManagerListener {
|
|
||||||
override fun templateStarted(state: TemplateState) {
|
|
||||||
if (!VimPlugin.isEnabled()) return
|
|
||||||
val editor = state.editor ?: return
|
|
||||||
|
|
||||||
state.addTemplateStateListener(object : TemplateEditingAdapter() {
|
|
||||||
override fun currentVariableChanged(templateState: TemplateState, template: Template?, oldIndex: Int, newIndex: Int) {
|
|
||||||
if (IdeaRefactorMode.keepMode()) {
|
|
||||||
IdeaRefactorMode.correctSelection(editor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (IdeaRefactorMode.keepMode()) {
|
|
||||||
IdeaRefactorMode.correctSelection(editor)
|
|
||||||
} else {
|
|
||||||
if (!editor.selectionModel.hasSelection()) {
|
|
||||||
// Enable insert mode if there is no selection in template
|
|
||||||
// Template with selection is handled by [com.maddyhome.idea.vim.group.visual.VisualMotionGroup.controlNonVimSelectionChange]
|
|
||||||
if (editor.inNormalMode) {
|
|
||||||
VimPlugin.getChange().insertBeforeCursor(editor, EditorDataContext.init(editor))
|
|
||||||
KeyHandler.getInstance().reset(editor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region Register shortcuts for lookup and perform partial reset
|
|
||||||
private object LookupListener : PropertyChangeListener {
|
|
||||||
override fun propertyChange(evt: PropertyChangeEvent?) {
|
|
||||||
if (evt == null) return
|
|
||||||
if (evt.propertyName == "activeLookup" && evt.oldValue == null && evt.newValue != null) {
|
|
||||||
val lookup = evt.newValue
|
|
||||||
if (lookup is LookupImpl) {
|
|
||||||
VimPlugin.getKey().registerShortcutsForLookup(lookup)
|
|
||||||
|
|
||||||
lookup.addLookupListener(object : com.intellij.codeInsight.lookup.LookupListener {
|
|
||||||
override fun itemSelected(event: LookupEvent) {
|
|
||||||
// VIM-1858
|
|
||||||
KeyHandler.getInstance().partialReset(lookup.editor)
|
|
||||||
lookup.removeLookupListener(this)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region Hide Vim search highlights when showing IntelliJ search results
|
|
||||||
class VimFindModelListener : FindModelListener {
|
|
||||||
override fun findNextModelChanged() {
|
|
||||||
if (!VimPlugin.isEnabled()) return
|
|
||||||
VimPlugin.getSearch().clearSearchHighlight()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region Ace jump
|
|
||||||
fun aceJumpActive(): Boolean {
|
|
||||||
// This logic should be removed after creating more correct key processing.
|
|
||||||
return EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT)
|
|
||||||
.javaClass.name.startsWith("org.acejump.")
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region AppCode templates
|
|
||||||
/**
|
|
||||||
* A collection of hacks to improve the interaction with fancy AppCode templates
|
|
||||||
*/
|
|
||||||
object AppCodeTemplates {
|
|
||||||
private val facedAppCodeTemplate = Key.create<IntRange>("FacedAppCodeTemplate")
|
|
||||||
|
|
||||||
private const val TEMPLATE_START = "<#T##"
|
|
||||||
private const val TEMPLATE_END = "#>"
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun onMovement(
|
|
||||||
editor: @NotNull Editor,
|
|
||||||
caret: @NotNull Caret,
|
|
||||||
toRight: Boolean
|
|
||||||
) {
|
|
||||||
if (!PlatformUtils.isAppCode()) return
|
|
||||||
|
|
||||||
val offset = caret.offset
|
|
||||||
val offsetRightEnd = offset + TEMPLATE_START.length
|
|
||||||
val offsetLeftEnd = offset - 1
|
|
||||||
val templateRange = caret.getUserData(facedAppCodeTemplate)
|
|
||||||
if (templateRange == null) {
|
|
||||||
if (offsetRightEnd < editor.fileSize
|
|
||||||
&& editor.document.charsSequence.subSequence(offset, offsetRightEnd).toString() == TEMPLATE_START) {
|
|
||||||
caret.shake()
|
|
||||||
|
|
||||||
val templateEnd = editor.findTemplateEnd(offset) ?: return
|
|
||||||
|
|
||||||
caret.putUserData(facedAppCodeTemplate, offset..templateEnd)
|
|
||||||
}
|
|
||||||
if (offsetLeftEnd >= 0
|
|
||||||
&& offset + 1 <= editor.fileSize
|
|
||||||
&& editor.document.charsSequence.subSequence(offsetLeftEnd, offset + 1).toString() == TEMPLATE_END) {
|
|
||||||
caret.shake()
|
|
||||||
|
|
||||||
val templateStart = editor.findTemplateStart(offsetLeftEnd) ?: return
|
|
||||||
|
|
||||||
caret.putUserData(facedAppCodeTemplate, templateStart..offset)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (offset in templateRange) {
|
|
||||||
if (toRight) {
|
|
||||||
caret.moveToOffset(templateRange.last + 1)
|
|
||||||
} else {
|
|
||||||
caret.moveToOffset(templateRange.first)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
caret.putUserData(facedAppCodeTemplate, null)
|
|
||||||
caret.shake()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Editor.appCodeTemplateCaptured(): Boolean {
|
|
||||||
if (!PlatformUtils.isAppCode()) return false
|
|
||||||
return this.caretModel.allCarets.any { it.getUserData(facedAppCodeTemplate) != null }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Caret.shake() {
|
|
||||||
moveCaretRelatively(1, 0, false, false)
|
|
||||||
moveCaretRelatively(-1, 0, false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Editor.findTemplateEnd(start: Int): Int? {
|
|
||||||
val charSequence = this.document.charsSequence
|
|
||||||
val length = charSequence.length
|
|
||||||
for (i in start until length - 1) {
|
|
||||||
if (charSequence[i] == TEMPLATE_END[0] && charSequence[i+1] == TEMPLATE_END[1]) {
|
|
||||||
return i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Editor.findTemplateStart(start: Int): Int? {
|
|
||||||
val charSequence = this.document.charsSequence
|
|
||||||
val templateLastIndex = TEMPLATE_START.length
|
|
||||||
for (i in start downTo templateLastIndex) {
|
|
||||||
if (charSequence.subSequence(i - templateLastIndex, i + 1).toString() == TEMPLATE_START) {
|
|
||||||
return i - templateLastIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
//region Find action ID
|
|
||||||
class FindActionIdAction : DumbAwareToggleAction() {
|
|
||||||
override fun isSelected(e: AnActionEvent): Boolean = FindActionId.enabled
|
|
||||||
|
|
||||||
override fun setSelected(e: AnActionEvent, state: Boolean) {
|
|
||||||
FindActionId.enabled = state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object FindActionId {
|
|
||||||
var enabled = false
|
|
||||||
}
|
|
||||||
//endregion
|
|
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
|
||||||
* Copyright (C) 2003-2021 The IdeaVim authors
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.maddyhome.idea.vim.option;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NonNls;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
public class BoundListOption extends ListOption {
|
|
||||||
BoundListOption(@NonNls String name, @NonNls String abbrev, @NonNls String[] dflt, @NonNls String[] values) {
|
|
||||||
super(name, abbrev, dflt, null);
|
|
||||||
|
|
||||||
this.values = new ArrayList<>(Arrays.asList(values));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean set(String val) {
|
|
||||||
List<String> vals = parseVals(val);
|
|
||||||
if (vals != null && values.containsAll(vals)) {
|
|
||||||
set(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean append(String val) {
|
|
||||||
List<String> vals = parseVals(val);
|
|
||||||
if (vals != null && values.containsAll(vals)) {
|
|
||||||
append(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean prepend(String val) {
|
|
||||||
List<String> vals = parseVals(val);
|
|
||||||
if (vals != null && values.containsAll(vals)) {
|
|
||||||
prepend(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean remove(String val) {
|
|
||||||
List<String> vals = parseVals(val);
|
|
||||||
if (vals != null && values.containsAll(vals)) {
|
|
||||||
remove(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final @NotNull List<String> values;
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
package icons;
|
|
||||||
|
|
||||||
import com.intellij.ui.IconManager;
|
|
||||||
import org.jetbrains.annotations.NonNls;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
|
|
||||||
public final class VimIcons {
|
|
||||||
private static @NotNull Icon load(@NotNull @NonNls String path) {
|
|
||||||
return IconManager.getInstance().getIcon(path, VimIcons.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final @NotNull Icon IDEAVIM = load("/icons/ideavim.svg");
|
|
||||||
public static final @NotNull Icon IDEAVIM_DISABLED = load("/icons/ideavim_disabled.svg");
|
|
||||||
public static final @NotNull Icon GITHUB = load("/icons/github.svg");
|
|
||||||
public static final @NotNull Icon TWITTER = load("/icons/twitter.svg");
|
|
||||||
public static final @NotNull Icon YOUTRACK = load("/icons/youtrack.svg");
|
|
||||||
}
|
|
808
src/main/antlr/Vimscript.g4
Normal file
@@ -0,0 +1,808 @@
|
|||||||
|
grammar Vimscript;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Multiline blocks related rules
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
script:
|
||||||
|
augroup? blockMember* EOF;
|
||||||
|
|
||||||
|
forLoop:
|
||||||
|
(WS | COLON)* FOR WS+ ((variableScope COLON)? variableName | (L_BRACKET argumentsDeclaration R_BRACKET)) WS+ IN WS* expr WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)+)
|
||||||
|
blockMember*
|
||||||
|
(WS | COLON)* ENDFOR WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)+)
|
||||||
|
;
|
||||||
|
|
||||||
|
whileLoop:
|
||||||
|
(WS | COLON)* WHILE WS* expr WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
(WS | COLON)* ENDWHILE WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
;
|
||||||
|
blockMember:
|
||||||
|
command | finishStatement | continueStatement | breakStatement | forLoop| whileLoop | ifStatement
|
||||||
|
| returnStatement | throwStatement | functionDefinition | tryStatement | ((WS | COLON)* (NEW_LINE | BAR)) | autoCmd | comment;
|
||||||
|
|
||||||
|
comment: (WS | COLON)* QUOTE ~(NEW_LINE)* NEW_LINE;
|
||||||
|
|
||||||
|
finishStatement: (WS | COLON)* FINISH WS* (NEW_LINE | BAR);
|
||||||
|
continueStatement: (WS | COLON)* CONTINUE WS* (NEW_LINE | BAR);
|
||||||
|
breakStatement: (WS | COLON)* BREAK WS* (NEW_LINE | BAR);
|
||||||
|
returnStatement: (WS | COLON)* range? (WS | COLON)* RETURN WS+ expr WS* (NEW_LINE | BAR);
|
||||||
|
throwStatement: (WS | COLON)* THROW WS+ expr WS* (NEW_LINE | BAR);
|
||||||
|
|
||||||
|
ifStatement: ifBlock
|
||||||
|
elifBlock*
|
||||||
|
elseBlock?
|
||||||
|
(WS | COLON)* ENDIF WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
;
|
||||||
|
ifBlock: (WS | COLON)* IF WS* expr WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
;
|
||||||
|
elifBlock: (WS | COLON)* ELSEIF WS* expr WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
;
|
||||||
|
elseBlock: (WS | COLON)* ELSE WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
;
|
||||||
|
|
||||||
|
tryStatement: tryBlock
|
||||||
|
catchBlock*
|
||||||
|
finallyBlock?
|
||||||
|
(WS | COLON)* ENDTRY WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
;
|
||||||
|
tryBlock: (WS | COLON)* TRY WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
;
|
||||||
|
catchBlock: (WS | COLON)* CATCH WS* pattern? WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
;
|
||||||
|
pattern: DIV patternBody DIV;
|
||||||
|
patternBody: ~(NEW_LINE | BAR)*?;
|
||||||
|
finallyBlock: (WS | COLON)* FINALLY WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
blockMember*
|
||||||
|
;
|
||||||
|
|
||||||
|
functionDefinition:
|
||||||
|
(WS | COLON)* FUNCTION (replace = EXCLAMATION)? WS+ (SID | SNR)? (anyCaseNameWithDigitsAndUnderscores NUM)* (functionScope COLON)? (functionName | (literalDictionaryKey (DOT literalDictionaryKey)+)) WS* L_PAREN WS* argumentsDeclaration WS* R_PAREN WS* (functionFlag WS*)* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)+)
|
||||||
|
blockMember*
|
||||||
|
(WS | COLON)* ENDFUNCTION WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR))
|
||||||
|
;
|
||||||
|
functionFlag: RANGE | ABORT | DICT | CLOSURE;
|
||||||
|
argumentsDeclaration: (ETC | defaultValue (WS* COMMA WS* defaultValue)* (WS* COMMA WS* ETC WS*)? | (variableName (WS* COMMA WS* variableName)* (WS* COMMA WS* defaultValue)* (WS* COMMA WS* ETC WS*)?))?;
|
||||||
|
defaultValue: variableName WS* ASSIGN WS* expr;
|
||||||
|
|
||||||
|
autoCmd: (WS | COLON)* AUTOCMD commandArgument = ~(NEW_LINE)*? NEW_LINE;
|
||||||
|
|
||||||
|
augroup: (WS | COLON)* AUGROUP .*? AUGROUP WS+ END WS* NEW_LINE;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Command related rules:
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
command:
|
||||||
|
(WS | COLON)* (range | shortRange) (WS | COLON)* (NEW_LINE | BAR)+
|
||||||
|
#GoToLineCommand|
|
||||||
|
|
||||||
|
// (WS | COLON)* range? (WS | COLON)* LET WS+ (~(NEW_LINE | BAR)+ | string)+ (NEW_LINE | BAR)+
|
||||||
|
letCommands
|
||||||
|
#LetCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* ECHO (WS* expr)* WS* (NEW_LINE | BAR)+
|
||||||
|
#EchoCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* DELF (replace = EXCLAMATION)? WS+ (functionScope COLON)? functionName ((inline_comment NEW_LINE+) | (NEW_LINE | BAR)+)
|
||||||
|
#DelfunctionCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* CALL WS+ expr WS* ((inline_comment NEW_LINE+) | (NEW_LINE | BAR)+)
|
||||||
|
#CallCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* EXECUTE WS* (expr WS*)* (NEW_LINE | BAR)+
|
||||||
|
#ExecuteCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* lShift (WS* commandArgument = ~(NEW_LINE | BAR)+)? ((inline_comment NEW_LINE+) | (NEW_LINE | BAR)+)
|
||||||
|
#ShiftLeftCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* rShift (WS* commandArgument = ~(NEW_LINE | BAR)+)? ((inline_comment NEW_LINE+) | (NEW_LINE | BAR)+)
|
||||||
|
#ShiftRightCommand|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)*
|
||||||
|
name = (
|
||||||
|
Y_LOWERCASE | YANK_LINES | X_LOWERCASE | WRITE_QUIT | WRITE_PREVIOUS | WRITE_NEXT | W_LOWERCASE | WRITE
|
||||||
|
| WRITE_ALL | U_LOWERCASE | UNDO | TAB_ONLY | TAB_CLOSE | SOURCE | V_SPLIT | SPLIT | SHELL | SET_HANDLER | SET | SETLOCAL
|
||||||
|
| SELECT_LAST_FILE | SELECT_FIRST_FILE | SELECT_FILE | AT | REDO | Q_LOWERCASE | QUIT | PUT_LINES | PROMPT_FIND
|
||||||
|
| PROMPT_REPLACE | P_LOWERCASE | P_UPPERCASE | PRINT | PREVIOUS_TAB | N_UPPERCASE | PREVIOUS_FILE | PLUG
|
||||||
|
| ONLY | NO_HL_SEARCH | NEXT_TAB | N_LOWERCASE | NEXT_FILE | M_LOWERCASE | MOVE_TEXT | MARKS | K_LOWERCASE
|
||||||
|
| MARK_COMMAND | JUMPS | J_LOWERCASE | JOIN_LINES | HISTORY | GO_TO_CHAR | SYMBOL | FIND | CLASS | F_LOWERCASE
|
||||||
|
| FILE | EXIT | E_LOWERCASE | EDIT_FILE | DUMP_LINE | DIGRAPH | DEL_MARKS | D_LOWERCASE | DEL_LINES | DELCMD
|
||||||
|
| T_LOWERCASE | COPY | CMD_CLEAR | BUFFER_LIST | BUFFER_CLOSE | B_LOWERCASE | BUFFER | ASCII
|
||||||
|
| ACTIONLIST | ACTION | LOCKVAR | UNLOCKVAR | PACKADD
|
||||||
|
)
|
||||||
|
WS* ((commandArgumentWithoutBars? inline_comment NEW_LINE) | (commandArgumentWithoutBars? NEW_LINE) | (commandArgumentWithoutBars? BAR)) (NEW_LINE | BAR)*
|
||||||
|
#CommandWithComment|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)*
|
||||||
|
name = (
|
||||||
|
MAP | MAP_CLEAR | UNMAP | SORT | REGISTERS | CMD | H_LOWERCASE | HELP | NORMAL
|
||||||
|
)
|
||||||
|
WS* commandArgumentWithoutBars? (NEW_LINE | BAR)+
|
||||||
|
#CommandWithoutComments|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)*
|
||||||
|
name = (
|
||||||
|
G_LOWERCASE | GLOBAL | V_LOWERCASE | V_GLOBAL | S_LOWERCASE | SUBSTITUTE | TILDE | AMPERSAND | EXCLAMATION
|
||||||
|
)
|
||||||
|
WS* commandArgumentWithBars? NEW_LINE+
|
||||||
|
#CommandWithBars|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* commandName WS* commandArgumentWithBars? (NEW_LINE | BAR)+
|
||||||
|
#OtherCommand
|
||||||
|
;
|
||||||
|
commandArgumentWithBars: ~(NEW_LINE)+;
|
||||||
|
commandArgumentWithoutBars: ~(NEW_LINE | BAR)+;
|
||||||
|
lShift: LESS+;
|
||||||
|
rShift: GREATER+;
|
||||||
|
|
||||||
|
letCommands:
|
||||||
|
(WS | COLON)* range? (WS | COLON)* LET WS+ expr WS*
|
||||||
|
assignmentOperator = (ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN | STAR_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | DOT_ASSIGN)
|
||||||
|
WS* expr WS* ((inline_comment NEW_LINE) | (NEW_LINE | BAR)+)
|
||||||
|
#Let1Command|
|
||||||
|
|
||||||
|
(WS | COLON)* range? (WS | COLON)* LET WS+ commandArgument = ~(NEW_LINE)* NEW_LINE+
|
||||||
|
#Let2Command
|
||||||
|
;
|
||||||
|
|
||||||
|
shortRange:
|
||||||
|
((QUESTION (~QUESTION)* QUESTION?) | (DIV (~DIV)* DIV?));
|
||||||
|
range:
|
||||||
|
rangeUnit+;
|
||||||
|
|
||||||
|
rangeUnit:
|
||||||
|
(rangeExpression? WS* rangeSeparator WS*) | (rangeExpression WS* rangeSeparator? WS*);
|
||||||
|
|
||||||
|
rangeExpression:
|
||||||
|
(rangeMember rangeOffset?) | (rangeMember? rangeOffset);
|
||||||
|
|
||||||
|
rangeMember:
|
||||||
|
unsignedInt | DOT | MOD | DOLLAR | ESCAPED_QUESTION | ESCAPED_AMPERSAND | ESCAPED_SLASH | mark | search+;
|
||||||
|
|
||||||
|
rangeSeparator:
|
||||||
|
COMMA | SEMI;
|
||||||
|
|
||||||
|
search:
|
||||||
|
(QUESTION (~QUESTION)*? QUESTION)
|
||||||
|
| (DIV (~DIV)*? DIV)
|
||||||
|
;
|
||||||
|
rangeOffset:
|
||||||
|
(numberInOffset | plusOneOffset | minusOneOffset )+;
|
||||||
|
numberInOffset:
|
||||||
|
(PLUS | MINUS)? unsignedInt;
|
||||||
|
plusOneOffset:
|
||||||
|
PLUS;
|
||||||
|
minusOneOffset:
|
||||||
|
MINUS;
|
||||||
|
|
||||||
|
commandName:
|
||||||
|
(LESS)+
|
||||||
|
| (GREATER)+
|
||||||
|
| anyCaseNameWithDigitsAndUnderscoresExceptKeywords
|
||||||
|
| commandName EXCLAMATION
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Expressions related rules
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
expr:
|
||||||
|
expr L_BRACKET expr R_BRACKET #OneElementSublistExpression
|
||||||
|
| WS* EXCLAMATION WS* expr #UnaryExpression
|
||||||
|
| expr L_BRACKET WS* from = expr? WS* COLON WS* to = expr? WS* R_BRACKET #SublistExpression
|
||||||
|
| expr WS* binaryOperator1 WS* expr #BinExpression1
|
||||||
|
| expr WS* binaryOperator2 WS* expr #BinExpression2
|
||||||
|
| expr WS* binaryOperator3 WS* expr #BinExpression3
|
||||||
|
| expr WS* binaryOperator4 WS* expr #BinExpression4
|
||||||
|
| expr WS* binaryOperator5 WS* expr #BinExpression5
|
||||||
|
| WS* unaryOperator = (PLUS | MINUS) WS* expr #UnaryExpression
|
||||||
|
| expr WS* ARROW WS* functionCall #FunctionAsMethodCall1
|
||||||
|
| expr WS* ARROW WS* lambda L_PAREN WS* functionArguments WS* R_PAREN #FunctionAsMethodCall2
|
||||||
|
| functionCall #FunctionCallExpression
|
||||||
|
| lambda L_PAREN WS* functionArguments WS* R_PAREN #LambdaFunctionCallExpression
|
||||||
|
| lambda #LambdaExpression
|
||||||
|
| unsignedInt #IntExpression
|
||||||
|
| unsignedFloat #FloatExpression
|
||||||
|
| string #StringExpression
|
||||||
|
| blob #BlobExpression
|
||||||
|
| variable #VariableExpression
|
||||||
|
| option #OptionExpression
|
||||||
|
| envVariable #EnvVariableExpression
|
||||||
|
| register #RegisterExpression
|
||||||
|
| list #ListExpression
|
||||||
|
| dictionary #DictionaryExpression
|
||||||
|
| literalDictionary #LiteralDictionaryExpression
|
||||||
|
| L_PAREN WS* expr WS* R_PAREN #WrappedExpression
|
||||||
|
| expr WS* QUESTION QUESTION WS* expr #FalsyExpression
|
||||||
|
| expr WS* QUESTION WS* expr WS* COLON WS* expr #TernaryExpression
|
||||||
|
;
|
||||||
|
|
||||||
|
binaryOperator1: STAR | DIV | MOD;
|
||||||
|
binaryOperator2: PLUS | MINUS | DOT | (DOT DOT);
|
||||||
|
binaryOperator3: LESS | LESS_IC | LESS_CS
|
||||||
|
| GREATER | GREATER_IC | GREATER_CS
|
||||||
|
| LESS_OR_EQUALS | LESS_OR_EQUALS_IC | LESS_OR_EQUALS_CS
|
||||||
|
| GREATER_OR_EQUALS | GREATER_OR_EQUALS_IC | GREATER_OR_EQUALS_CS
|
||||||
|
| MATCHES | MATCHES_IC | MATCHES_CS
|
||||||
|
| NOT_MATCHES | NOT_MATCHES_IC | NOT_MATCHES_CS
|
||||||
|
| EQUALS | EQUALS_IC | EQUALS_CS
|
||||||
|
| NOT_EQUALS | NOT_EQUALS_IC | NOT_EQUALS_CS
|
||||||
|
| IS | IS_IC | IS_CS
|
||||||
|
| IS_NOT | IS_NOT_IC | IS_NOT_CS
|
||||||
|
;
|
||||||
|
binaryOperator4: AMPERSAND AMPERSAND;
|
||||||
|
binaryOperator5: LOGICAL_OR;
|
||||||
|
|
||||||
|
register: AT (DIGIT | lowercaseAlphabeticChar | uppercaseAlphabeticChar | MINUS | COLON | DOT | MOD | NUM | ASSIGN | STAR | PLUS | TILDE | UNDERSCORE | DIV | AT | QUOTE);
|
||||||
|
// todo argumentDeclaration but without default values
|
||||||
|
lambda: L_CURLY WS* argumentsDeclaration WS* ARROW WS* expr WS* R_CURLY;
|
||||||
|
|
||||||
|
variable: (variableScope COLON)? variableName;
|
||||||
|
variableName: curlyBracesName;
|
||||||
|
variableScope: anyScope;
|
||||||
|
|
||||||
|
curlyBracesName: element+;
|
||||||
|
element: anyCaseNameWithDigitsAndUnderscores | unsignedInt | L_CURLY WS* expr WS* R_CURLY;
|
||||||
|
|
||||||
|
option: AMPERSAND (optionScope COLON)? optionName;
|
||||||
|
optionName: anyCaseNameWithDigitsAndUnderscores;
|
||||||
|
optionScope: anyScope;
|
||||||
|
|
||||||
|
envVariable: DOLLAR envVariableName;
|
||||||
|
envVariableName: anyCaseNameWithDigitsAndUnderscores;
|
||||||
|
|
||||||
|
functionCall: (functionScope COLON)? (anyCaseNameWithDigitsAndUnderscores NUM)* functionName WS* L_PAREN WS* functionArguments WS* R_PAREN;
|
||||||
|
functionName: curlyBracesName;
|
||||||
|
functionScope: anyScope;
|
||||||
|
functionArguments: (functionArgument WS* (COMMA WS* functionArgument WS*)*)?;
|
||||||
|
functionArgument: expr | (anyScope COLON);
|
||||||
|
|
||||||
|
list: L_BRACKET WS* (expr WS* (COMMA WS* expr WS*)*)? COMMA? WS* R_BRACKET;
|
||||||
|
|
||||||
|
dictionary: L_CURLY WS* (dictionaryEntry WS* (COMMA WS* dictionaryEntry WS*)*)? COMMA? WS* R_CURLY;
|
||||||
|
dictionaryEntry: expr WS* COLON WS* expr;
|
||||||
|
|
||||||
|
literalDictionary: NUM L_CURLY WS* (literalDictionaryEntry WS* (COMMA WS* literalDictionaryEntry WS*)* COMMA? WS*)? R_CURLY;
|
||||||
|
literalDictionaryEntry: literalDictionaryKey WS* COLON WS* expr;
|
||||||
|
literalDictionaryKey: anyCaseNameWithDigitsAndUnderscores
|
||||||
|
| unsignedInt
|
||||||
|
| literalDictionaryKey MINUS+ literalDictionaryKey
|
||||||
|
| MINUS+ literalDictionaryKey
|
||||||
|
| literalDictionaryKey MINUS+
|
||||||
|
;
|
||||||
|
|
||||||
|
anyScope: B_LOWERCASE // buffer variable
|
||||||
|
| W_LOWERCASE // window variable
|
||||||
|
| T_LOWERCASE // tabpage variable
|
||||||
|
| G_LOWERCASE // global variable
|
||||||
|
| L_LOWERCASE // local variable
|
||||||
|
| S_LOWERCASE // script variable
|
||||||
|
| A_LOWERCASE // function variable
|
||||||
|
| V_LOWERCASE // vim variable
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Names and vim datatypes
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
string:
|
||||||
|
QUOTE ~(NEW_LINE | QUOTE)* QUOTE
|
||||||
|
| ESCAPED_SINGLE_QUOTE
|
||||||
|
| ESCAPED_SINGLE_QUOTE ESCAPED_SINGLE_QUOTE
|
||||||
|
| (SINGLE_QUOTE | MARK_SINGLE_QUOTED | (ESCAPED_SINGLE_QUOTE SINGLE_QUOTE)) ~(SINGLE_QUOTE | NEW_LINE)*? SINGLE_QUOTE
|
||||||
|
;
|
||||||
|
unsignedFloat: FLOAT;
|
||||||
|
unsignedInt: DIGIT | INT;
|
||||||
|
blob: BLOB;
|
||||||
|
|
||||||
|
mark: (SINGLE_QUOTE (DIGIT | LESS | GREATER | L_PAREN | R_PAREN | L_CURLY | R_CURLY | L_BRACKET | R_BRACKET | QUOTE | CARET | DOT | BACKTICK | SINGLE_QUOTE))
|
||||||
|
| (BACKTICK (DIGIT | LESS | GREATER | L_PAREN | R_PAREN | L_CURLY | R_CURLY | L_BRACKET | R_BRACKET | QUOTE | CARET | DOT | BACKTICK | SINGLE_QUOTE))
|
||||||
|
| MARK_SINGLE_QUOTED
|
||||||
|
| MARK_BACKTICK
|
||||||
|
;
|
||||||
|
inline_comment: QUOTE ~(NEW_LINE)*?;
|
||||||
|
anyCaseNameWithDigitsAndUnderscores:
|
||||||
|
lowercaseAlphabeticChar
|
||||||
|
| uppercaseAlphabeticChar
|
||||||
|
| keyword
|
||||||
|
| IDENTIFIER_LOWERCASE
|
||||||
|
| IDENTIFIER_ANY_CASE
|
||||||
|
| anyCaseNameWithDigitsAndUnderscores (anyCaseNameWithDigitsAndUnderscores | DIGIT | INT | UNDERSCORE)+
|
||||||
|
;
|
||||||
|
|
||||||
|
anyCaseNameWithDigitsAndUnderscoresExceptKeywords:
|
||||||
|
lowercaseAlphabeticChar
|
||||||
|
| uppercaseAlphabeticChar
|
||||||
|
| IDENTIFIER_LOWERCASE
|
||||||
|
| IDENTIFIER_ANY_CASE
|
||||||
|
| anyCaseNameWithDigitsAndUnderscores (anyCaseNameWithDigitsAndUnderscores | DIGIT | INT | UNDERSCORE)+
|
||||||
|
;
|
||||||
|
|
||||||
|
uppercaseAlphabeticChar:
|
||||||
|
A_UPPERCASE
|
||||||
|
| B_UPPERCASE
|
||||||
|
| C_UPPERCASE
|
||||||
|
| D_UPPERCASE
|
||||||
|
| E_UPPERCASE
|
||||||
|
| F_UPPERCASE
|
||||||
|
| G_UPPERCASE
|
||||||
|
| H_UPPERCASE
|
||||||
|
| I_UPPERCASE
|
||||||
|
| J_UPPERCASE
|
||||||
|
| K_UPPERCASE
|
||||||
|
| L_UPPERCASE
|
||||||
|
| M_UPPERCASE
|
||||||
|
| N_UPPERCASE
|
||||||
|
| O_UPPERCASE
|
||||||
|
| P_UPPERCASE
|
||||||
|
| Q_UPPERCASE
|
||||||
|
| R_UPPERCASE
|
||||||
|
| S_UPPERCASE
|
||||||
|
| T_UPPERCASE
|
||||||
|
| U_UPPERCASE
|
||||||
|
| V_UPPERCASE
|
||||||
|
| W_UPPERCASE
|
||||||
|
| X_UPPERCASE
|
||||||
|
| Y_UPPERCASE
|
||||||
|
| Z_UPPERCASE
|
||||||
|
;
|
||||||
|
lowercaseAlphabeticChar:
|
||||||
|
A_LOWERCASE
|
||||||
|
| B_LOWERCASE
|
||||||
|
| C_LOWERCASE
|
||||||
|
| D_LOWERCASE
|
||||||
|
| E_LOWERCASE
|
||||||
|
| F_LOWERCASE
|
||||||
|
| G_LOWERCASE
|
||||||
|
| H_LOWERCASE
|
||||||
|
| I_LOWERCASE
|
||||||
|
| J_LOWERCASE
|
||||||
|
| K_LOWERCASE
|
||||||
|
| L_LOWERCASE
|
||||||
|
| M_LOWERCASE
|
||||||
|
| N_LOWERCASE
|
||||||
|
| O_LOWERCASE
|
||||||
|
| P_LOWERCASE
|
||||||
|
| Q_LOWERCASE
|
||||||
|
| R_LOWERCASE
|
||||||
|
| S_LOWERCASE
|
||||||
|
| T_LOWERCASE
|
||||||
|
| U_LOWERCASE
|
||||||
|
| V_LOWERCASE
|
||||||
|
| W_LOWERCASE
|
||||||
|
| X_LOWERCASE
|
||||||
|
| Y_LOWERCASE
|
||||||
|
| Z_LOWERCASE
|
||||||
|
;
|
||||||
|
|
||||||
|
keyword: FUNCTION
|
||||||
|
| ENDFUNCTION
|
||||||
|
| FOR
|
||||||
|
| ENDFOR
|
||||||
|
| IN
|
||||||
|
| BREAK
|
||||||
|
| CONTINUE
|
||||||
|
| WHILE
|
||||||
|
| ENDWHILE
|
||||||
|
| IF
|
||||||
|
| ELSE
|
||||||
|
| ELSEIF
|
||||||
|
| ENDIF
|
||||||
|
| THROW
|
||||||
|
| TRY
|
||||||
|
| CATCH
|
||||||
|
| FINALLY
|
||||||
|
| ENDTRY
|
||||||
|
| RANGE
|
||||||
|
| ABORT
|
||||||
|
| DICT
|
||||||
|
| CLOSURE
|
||||||
|
| AUTOCMD
|
||||||
|
| AUGROUP
|
||||||
|
| existingCommands
|
||||||
|
;
|
||||||
|
existingCommands: RETURN
|
||||||
|
| LET
|
||||||
|
| ECHO
|
||||||
|
| DELF
|
||||||
|
| ACTION
|
||||||
|
| ACTIONLIST
|
||||||
|
| ASCII
|
||||||
|
| BUFFER
|
||||||
|
| BUFFER_CLOSE
|
||||||
|
| BUFFER_LIST
|
||||||
|
| CMD
|
||||||
|
| CMD_CLEAR
|
||||||
|
| COPY
|
||||||
|
| DELCMD
|
||||||
|
| DEL_LINES
|
||||||
|
| DEL_MARKS
|
||||||
|
| DIGRAPH
|
||||||
|
| DUMP_LINE
|
||||||
|
| EDIT_FILE
|
||||||
|
| EXIT
|
||||||
|
| FILE
|
||||||
|
| CLASS
|
||||||
|
| FIND
|
||||||
|
| SYMBOL
|
||||||
|
| GLOBAL
|
||||||
|
| V_GLOBAL
|
||||||
|
| GO_TO_CHAR
|
||||||
|
| HELP
|
||||||
|
| HISTORY
|
||||||
|
| JOIN_LINES
|
||||||
|
| JUMPS
|
||||||
|
| MARK_COMMAND
|
||||||
|
| MARKS
|
||||||
|
| MOVE_TEXT
|
||||||
|
| NEXT_FILE
|
||||||
|
| NEXT_TAB
|
||||||
|
| NO_HL_SEARCH
|
||||||
|
| ONLY
|
||||||
|
| PACKADD
|
||||||
|
| PLUG
|
||||||
|
| PREVIOUS_FILE
|
||||||
|
| PREVIOUS_TAB
|
||||||
|
| PRINT
|
||||||
|
| PROMPT_FIND
|
||||||
|
| PROMPT_REPLACE
|
||||||
|
| PUT_LINES
|
||||||
|
| QUIT
|
||||||
|
| REDO
|
||||||
|
| REGISTERS
|
||||||
|
| SELECT_FILE
|
||||||
|
| SELECT_FIRST_FILE
|
||||||
|
| SELECT_LAST_FILE
|
||||||
|
| SET
|
||||||
|
| SETLOCAL
|
||||||
|
| SET_HANDLER
|
||||||
|
| SHELL
|
||||||
|
| SORT
|
||||||
|
| SPLIT
|
||||||
|
| V_SPLIT
|
||||||
|
| SOURCE
|
||||||
|
| SUBSTITUTE
|
||||||
|
| TAB_CLOSE
|
||||||
|
| TAB_ONLY
|
||||||
|
| UNDO
|
||||||
|
| WRITE_ALL
|
||||||
|
| WRITE
|
||||||
|
| WRITE_NEXT
|
||||||
|
| WRITE_PREVIOUS
|
||||||
|
| WRITE_QUIT
|
||||||
|
| YANK_LINES
|
||||||
|
| MAP
|
||||||
|
| MAP_CLEAR
|
||||||
|
| UNMAP
|
||||||
|
| EXECUTE
|
||||||
|
| CALL
|
||||||
|
| NORMAL
|
||||||
|
;
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Lexer rules
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Lowercase chars
|
||||||
|
A_LOWERCASE: 'a';
|
||||||
|
B_LOWERCASE: 'b';
|
||||||
|
C_LOWERCASE: 'c';
|
||||||
|
D_LOWERCASE: 'd';
|
||||||
|
E_LOWERCASE: 'e';
|
||||||
|
F_LOWERCASE: 'f';
|
||||||
|
G_LOWERCASE: 'g';
|
||||||
|
H_LOWERCASE: 'h';
|
||||||
|
I_LOWERCASE: 'i';
|
||||||
|
J_LOWERCASE: 'j';
|
||||||
|
K_LOWERCASE: 'k';
|
||||||
|
L_LOWERCASE: 'l';
|
||||||
|
M_LOWERCASE: 'm';
|
||||||
|
N_LOWERCASE: 'n';
|
||||||
|
O_LOWERCASE: 'o';
|
||||||
|
P_LOWERCASE: 'p';
|
||||||
|
Q_LOWERCASE: 'q';
|
||||||
|
R_LOWERCASE: 'r';
|
||||||
|
S_LOWERCASE: 's';
|
||||||
|
T_LOWERCASE: 't';
|
||||||
|
U_LOWERCASE: 'u';
|
||||||
|
V_LOWERCASE: 'v';
|
||||||
|
W_LOWERCASE: 'w';
|
||||||
|
X_LOWERCASE: 'x';
|
||||||
|
Y_LOWERCASE: 'y';
|
||||||
|
Z_LOWERCASE: 'z';
|
||||||
|
|
||||||
|
// Uppercase chars
|
||||||
|
A_UPPERCASE: 'A';
|
||||||
|
B_UPPERCASE: 'B';
|
||||||
|
C_UPPERCASE: 'C';
|
||||||
|
D_UPPERCASE: 'D';
|
||||||
|
E_UPPERCASE: 'E';
|
||||||
|
F_UPPERCASE: 'F';
|
||||||
|
G_UPPERCASE: 'G';
|
||||||
|
H_UPPERCASE: 'H';
|
||||||
|
I_UPPERCASE: 'I';
|
||||||
|
J_UPPERCASE: 'J';
|
||||||
|
K_UPPERCASE: 'K';
|
||||||
|
L_UPPERCASE: 'L';
|
||||||
|
M_UPPERCASE: 'M';
|
||||||
|
N_UPPERCASE: 'N';
|
||||||
|
O_UPPERCASE: 'O';
|
||||||
|
P_UPPERCASE: 'P';
|
||||||
|
Q_UPPERCASE: 'Q';
|
||||||
|
R_UPPERCASE: 'R';
|
||||||
|
S_UPPERCASE: 'S';
|
||||||
|
T_UPPERCASE: 'T';
|
||||||
|
U_UPPERCASE: 'U';
|
||||||
|
V_UPPERCASE: 'V';
|
||||||
|
W_UPPERCASE: 'W';
|
||||||
|
X_UPPERCASE: 'X';
|
||||||
|
Y_UPPERCASE: 'Y';
|
||||||
|
Z_UPPERCASE: 'Z';
|
||||||
|
|
||||||
|
MARK_SINGLE_QUOTED: '\''[a-zA-Z];
|
||||||
|
MARK_BACKTICK: '`'[a-zA-Z];
|
||||||
|
|
||||||
|
// Keywords
|
||||||
|
FUNCTION: 'fu' | 'fun' | 'func' | 'funct' | 'functi' | 'functio' | 'function';
|
||||||
|
ENDFUNCTION: 'endf' | 'endfu' | 'endfun' | 'endfunc' | 'endfunct' | 'endfuncti' | 'endfunctio' | 'endfunction';
|
||||||
|
RANGE: 'range';
|
||||||
|
ABORT: 'abort';
|
||||||
|
DICT: 'dict';
|
||||||
|
CLOSURE: 'closure';
|
||||||
|
FOR: 'for';
|
||||||
|
ENDFOR: 'endfo' | 'endfor';
|
||||||
|
IN: 'in';
|
||||||
|
BREAK: 'brea' | 'break';
|
||||||
|
CONTINUE: 'con' | 'cont' | 'conti' | 'contin' | 'continu' | 'continue';
|
||||||
|
FINISH: 'fini' | 'finis' | 'finish';
|
||||||
|
RETURN: 'return';
|
||||||
|
WHILE: 'wh' | 'whi' | 'whil' | 'while';
|
||||||
|
ENDWHILE: 'endw' | 'endwh' | 'endwhi' | 'endwhil' |'endwhile';
|
||||||
|
IF: 'if';
|
||||||
|
ELSE: 'el' | 'els' | 'else';
|
||||||
|
ELSEIF: 'elsei' | 'elseif';
|
||||||
|
ENDIF: 'en' | 'end' | 'endi' | 'endif';
|
||||||
|
TRY: 'try';
|
||||||
|
CATCH: 'cat' | 'catc'| 'catch';
|
||||||
|
FINALLY: 'fina' | 'final' | 'finall' | 'finally';
|
||||||
|
ENDTRY: 'endt' | 'endtr' | 'endtry';
|
||||||
|
THROW: 'throw';
|
||||||
|
SID: '<SID>';
|
||||||
|
SNR: '<SNR>';
|
||||||
|
AUTOCMD: 'au' | 'aut' | 'auto' | 'autoc' | 'autocm' | 'autocmd';
|
||||||
|
AUGROUP: 'aug' | 'augr' | 'augro' | 'augrou' | 'augroup';
|
||||||
|
END: 'END';
|
||||||
|
|
||||||
|
// Commands
|
||||||
|
ACTION: 'action';
|
||||||
|
ACTIONLIST: 'actionlist';
|
||||||
|
ASCII: 'as' | 'asc' | 'asci' | 'ascii';
|
||||||
|
BUFFER: 'bu' | 'buf' | 'buff' | 'buffe' | 'buffer';
|
||||||
|
BUFFER_CLOSE: 'bd' | 'bde' | 'bdel' | 'bdele' | 'bdelet' | 'bdelete';
|
||||||
|
BUFFER_LIST: 'buffers' | 'ls' | 'files';
|
||||||
|
CALL: 'cal' | 'call';
|
||||||
|
CLASS: 'cla' | 'clas' | 'class';
|
||||||
|
CMD: 'com' | 'comm' | 'comma' | 'comman' | 'command';
|
||||||
|
CMD_CLEAR: 'comc' | 'comcl' | 'comcle' | 'comclea' | 'comclear';
|
||||||
|
COPY: 'co' | 'cop' | 'copy';
|
||||||
|
DELCMD: 'delc' | 'delco' | 'delcom' | 'delcomm' | 'delcomma' | 'delcomman' | 'delcommand';
|
||||||
|
DELF: 'delf' | 'delfu' | 'delfun' | 'delfunc'| 'delfunct' | 'delfuncti' | 'delfunctio' | 'delfunction';
|
||||||
|
DEL_LINES: 'de' | 'del' | 'dele' | 'delet' | 'delete';
|
||||||
|
DEL_MARKS: 'delm' | 'delma' | 'delmar' | 'delmark' | 'delmarks';
|
||||||
|
DIGRAPH: 'dig' | 'digr' | 'digra' | 'digrap' | 'digraph' | 'digraphs';
|
||||||
|
DUMP_LINE: 'dump' | 'dumpl' | 'dumpli' | 'dumplin' | 'dumpline';
|
||||||
|
ECHO: 'ec' | 'ech' | 'echo';
|
||||||
|
EDIT_FILE: 'bro' | 'brow' | 'brows' | 'browse' | 'ed' | 'edi' | 'edit';
|
||||||
|
EXIT: 'wqa' | 'wqal' | 'wqall' | 'qa' | 'qal' | 'qall' | 'xa' | 'xal' | 'xall' | 'quita' | 'quital' | 'quitall';
|
||||||
|
FILE: 'fi' | 'fil' | 'file';
|
||||||
|
FIND: 'fin' | 'find';
|
||||||
|
GLOBAL: 'gl' | 'glo' | 'glob' | 'globa' | 'global';
|
||||||
|
GO_TO_CHAR: 'go' | 'got' | 'goto';
|
||||||
|
HELP: 'he' | 'hel' | 'help';
|
||||||
|
HISTORY: 'his' | 'hist' | 'histo' | 'histor' | 'history';
|
||||||
|
JOIN_LINES: 'jo' | 'joi' | 'join';
|
||||||
|
JUMPS: 'ju' | 'jum' | 'jump' | 'jumps';
|
||||||
|
LET: 'let';
|
||||||
|
MARKS: 'marks';
|
||||||
|
MARK_COMMAND: 'ma' | 'mar' | 'mark';
|
||||||
|
MOVE_TEXT: 'mo' | 'mov' | 'move';
|
||||||
|
NEXT_FILE: 'ne' | 'nex' | 'next' | 'bn' | 'bne' | 'bnex' | 'bnext';
|
||||||
|
NEXT_TAB: 'tabn' | 'tabne' | 'tabnex' | 'tabnext';
|
||||||
|
NO_HL_SEARCH: 'noh' | 'nohl' | 'nohls' | 'nohlse' | 'nohlsea' | 'nohlsear' | 'nohlsearc' | 'nohlsearch';
|
||||||
|
ONLY: 'on' | 'onl' | 'only';
|
||||||
|
PACKADD: 'pa' | 'pac' | 'pack' | 'packa' | 'packad' | 'packadd';
|
||||||
|
PLUG: 'Plug' | 'Plugi' | 'Plugin';
|
||||||
|
PREVIOUS_FILE: 'Ne' | 'Nex' | 'Next' | 'prev'| 'previ' | 'previo' | 'previou' | 'previous' | 'bp' | 'bpr' | 'bpre' |'bprev'| 'bprevi' | 'bprevio' | 'bpreviou' | 'bprevious';
|
||||||
|
PREVIOUS_TAB: 'tabp' | 'tabpr' | 'tabpre' | 'tabprev' | 'tabprevi' | 'tabprevio' | 'tabpreviou' | 'tabprevious' | 'tabN' | 'tabNe' | 'tabNex' | 'tabNext';
|
||||||
|
PRINT: 'pr' | 'pri' | 'prin' | 'print' | 'Pr' | 'Pri' | 'Prin' | 'Print';
|
||||||
|
PROMPT_FIND: 'pro' | 'prom' | 'promp' | 'prompt' | 'promptf' | 'promptfi' | 'promptfin' | 'promptfind';
|
||||||
|
PROMPT_REPLACE: 'promptr' | 'promptre' | 'promptrep' | 'promptrepl';
|
||||||
|
PUT_LINES: 'pu' | 'put';
|
||||||
|
QUIT: 'qu' | 'qui' | 'quit' | 'clo' | 'clos' | 'close' | 'hid' | 'hide';
|
||||||
|
REDO: 'red' | 'redo';
|
||||||
|
REGISTERS: 'di' | 'dis' | 'disp' | 'displ' | 'displa' | 'display' | 'reg' | 'regi' | 'regis' | 'regist' | 'registe' | 'register' | 'registers';
|
||||||
|
SYMBOL: 'sym' | 'symb' | 'symbo' | 'symbol';
|
||||||
|
V_GLOBAL: 'vg' | 'vgl' | 'vglo' | 'vglob' | 'vgloba' | 'vglobal';
|
||||||
|
SELECT_FILE: 'argu' | 'argum' | 'argume' | 'argumen' | 'argument';
|
||||||
|
SELECT_FIRST_FILE: 'fir' | 'firs' | 'first';
|
||||||
|
SELECT_LAST_FILE: 'la' | 'las' | 'last';
|
||||||
|
SET: 'se' | 'set';
|
||||||
|
SETLOCAL: 'setl' | 'setlo' | 'setloc' | 'setloca' | 'setlocal';
|
||||||
|
SET_HANDLER: 'sethandler';
|
||||||
|
SHELL: 'sh' | 'she' | 'shel' | 'shell';
|
||||||
|
SORT: 'sor' | 'sort';
|
||||||
|
SPLIT: 'sp' | 'spl' | 'spli' | 'split';
|
||||||
|
V_SPLIT: 'vs' | 'vsp' | 'vspl' | 'vspli' | 'vsplit';
|
||||||
|
SOURCE: 'so' | 'sou' | 'sour' | 'sourc' | 'source';
|
||||||
|
SUBSTITUTE: 'su' | 'sub' | 'subs' | 'subst' | 'substi' | 'substit' | 'substitu' | 'substitut' | 'substitute';
|
||||||
|
TAB_CLOSE: 'tabc' | 'tabcl' | 'tabclo' | 'tabclos' | 'tabclose';
|
||||||
|
TAB_ONLY: 'tabo' | 'tabon' | 'tabonl' | 'tabonly';
|
||||||
|
UNDO: 'un' | 'und' | 'undo';
|
||||||
|
WRITE_ALL: 'wa' | 'wal' | 'wall';
|
||||||
|
WRITE: 'wr' | 'wri' | 'writ' | 'write';
|
||||||
|
WRITE_NEXT: 'wn' | 'wne' | 'wnex' | 'wnext';
|
||||||
|
WRITE_PREVIOUS: 'wN' | 'wNe' | 'wNex' | 'wNext' | 'wp' | 'wpr' | 'wpre' | 'wprev' | 'wprevi' | 'wprevio' | 'wpreviou' | 'wprevious';
|
||||||
|
WRITE_QUIT: 'wq' | 'exi' | 'exit' | 'xi' | 'xit';
|
||||||
|
YANK_LINES: 'ya' | 'yan' | 'yank';
|
||||||
|
MAP_CLEAR: ('mapc' | 'nmapc' | 'vmapc' | 'xmapc' | 'smapc' | 'omapc' | 'imapc' | 'cmapc')
|
||||||
|
| (('mapc' | 'nmapc' | 'vmapc' | 'xmapc' | 'smapc' | 'omapc' | 'imapc' | 'cmapc') 'l')
|
||||||
|
| (('mapc' | 'nmapc' | 'vmapc' | 'xmapc' | 'smapc' | 'omapc' | 'imapc' | 'cmapc') 'le')
|
||||||
|
| (('mapc' | 'nmapc' | 'vmapc' | 'xmapc' | 'smapc' | 'omapc' | 'imapc' | 'cmapc') 'lea')
|
||||||
|
| (('mapc' | 'nmapc' | 'vmapc' | 'xmapc' | 'smapc' | 'omapc' | 'imapc' | 'cmapc') 'lear');
|
||||||
|
MAP: 'map'
|
||||||
|
| 'nm' | 'vm' | 'xm' | 'om' | 'im' | 'cm'
|
||||||
|
| (('nm' | 'vm' | 'xm' | 'om' | 'im' | 'cm') 'a')
|
||||||
|
| (('nm' | 'vm' | 'xm' | 'om' | 'im' | 'cm') 'ap')
|
||||||
|
| 'no' | 'nn' | 'vn' | 'xn' | 'ono' | 'ino' | 'cno'
|
||||||
|
| 'nno' | 'vno' | 'xno'
|
||||||
|
| (('no' | 'nno' | 'vno' | 'xno' | 'ono' | 'ino' | 'cno') 'r')
|
||||||
|
| (('no' | 'nno' | 'vno' | 'xno' | 'ono' | 'ino' | 'cno') 're')
|
||||||
|
| (('no' | 'nno' | 'vno' | 'xno' | 'ono' | 'ino' | 'cno') 'rem')
|
||||||
|
| (('no' | 'nno' | 'vno' | 'xno' | 'ono' | 'ino' | 'cno') 'rema')
|
||||||
|
| (('no' | 'nno' | 'vno' | 'xno' | 'ono' | 'ino' | 'cno') 'remap');
|
||||||
|
UNMAP: 'unm' | 'nun' | 'vu' | 'xu' | 'sunm' | 'ou' | 'iu' | 'cu'
|
||||||
|
| 'vun' | 'xun' | 'oun' | 'iun' | 'cun'
|
||||||
|
| 'nunm' | 'vunm' | 'xunm' | 'ounm' | 'iunm' | 'cunm'
|
||||||
|
| 'unma' | 'nunma' | 'vunma' | 'xunma' | 'sunma' | 'ounma' | 'iunma' | 'cunma'
|
||||||
|
| 'unmap' | 'nunmap' | 'vunmap' | 'xunmap' | 'sunmap' | 'ounmap' | 'iunmap' | 'cunmap';
|
||||||
|
EXECUTE: 'exe' | 'exec' | 'execu' | 'execut' | 'execute';
|
||||||
|
LOCKVAR: 'lockv' | 'lockva' | 'lockvar';
|
||||||
|
UNLOCKVAR: 'unlo' | 'unloc' | 'unlock' | 'unlockv' | 'unlockva' | 'unlockvar';
|
||||||
|
NORMAL: 'norm' | 'norma' | 'normal';
|
||||||
|
|
||||||
|
// Types
|
||||||
|
DIGIT: [0-9];
|
||||||
|
INT: [0-9]+
|
||||||
|
| '0'[xX][0-9a-fA-F]+;
|
||||||
|
FLOAT: [0-9]+'.'[0-9]+
|
||||||
|
| [0-9]+'.'[0-9]+'e'[+-]?[0-9]+
|
||||||
|
;
|
||||||
|
BLOB: '0'[zZ][0-9a-fA-F]+;
|
||||||
|
QUOTE: '"';
|
||||||
|
SINGLE_QUOTE: '\'';
|
||||||
|
ESCAPED_SINGLE_QUOTE: '\'\'';
|
||||||
|
ESCAPED_DOUBLE_QUOTE: '\\"';
|
||||||
|
|
||||||
|
// Identifiers
|
||||||
|
IDENTIFIER_LOWERCASE: [a-z]+;
|
||||||
|
IDENTIFIER_ANY_CASE: [a-zA-Z]+;
|
||||||
|
|
||||||
|
// Unary operators
|
||||||
|
EXCLAMATION: '!';
|
||||||
|
|
||||||
|
// Punctuation
|
||||||
|
L_PAREN: '(';
|
||||||
|
R_PAREN: ')';
|
||||||
|
L_CURLY: '{';
|
||||||
|
R_CURLY: '}';
|
||||||
|
L_BRACKET: '[';
|
||||||
|
R_BRACKET: ']';
|
||||||
|
COMMA: ',';
|
||||||
|
SEMI: ';';
|
||||||
|
COLON: ':';
|
||||||
|
QUESTION: '?';
|
||||||
|
DOLLAR: '$';
|
||||||
|
AMPERSAND: '&';
|
||||||
|
UNDERSCORE: '_';
|
||||||
|
TILDE: '~';
|
||||||
|
NUM: '#';
|
||||||
|
AT: '@';
|
||||||
|
CARET: '^';
|
||||||
|
BACKTICK: '`';
|
||||||
|
BAR: '|';
|
||||||
|
ETC: '...';
|
||||||
|
ARROW: '->';
|
||||||
|
|
||||||
|
// Mixed operators
|
||||||
|
PLUS: '+';
|
||||||
|
MINUS: '-';
|
||||||
|
|
||||||
|
// Binary operators
|
||||||
|
STAR: '*';
|
||||||
|
DIV: '/';
|
||||||
|
MOD: '%';
|
||||||
|
DOT: '.';
|
||||||
|
|
||||||
|
// Logical operators
|
||||||
|
LOGICAL_OR: '||';
|
||||||
|
|
||||||
|
// Relation operators
|
||||||
|
LESS: '<';
|
||||||
|
LESS_IC: '<?';
|
||||||
|
LESS_CS: '<#';
|
||||||
|
GREATER: '>';
|
||||||
|
GREATER_IC: '>?';
|
||||||
|
GREATER_CS: '>#';
|
||||||
|
LESS_OR_EQUALS: '<=';
|
||||||
|
LESS_OR_EQUALS_IC: '<=?';
|
||||||
|
LESS_OR_EQUALS_CS: '<=#';
|
||||||
|
GREATER_OR_EQUALS: '>=';
|
||||||
|
GREATER_OR_EQUALS_IC: '>=?';
|
||||||
|
GREATER_OR_EQUALS_CS: '>=#';
|
||||||
|
EQUALS: '==';
|
||||||
|
EQUALS_IC: '==?';
|
||||||
|
EQUALS_CS: '==#';
|
||||||
|
NOT_EQUALS: '!=';
|
||||||
|
NOT_EQUALS_IC: '!=?';
|
||||||
|
NOT_EQUALS_CS: '!=#';
|
||||||
|
MATCHES: '=~';
|
||||||
|
MATCHES_IC: '=~?';
|
||||||
|
MATCHES_CS: '=~#';
|
||||||
|
NOT_MATCHES: '!~';
|
||||||
|
NOT_MATCHES_IC: '!~?';
|
||||||
|
NOT_MATCHES_CS: '!~#';
|
||||||
|
IS: 'is';
|
||||||
|
IS_IC: 'is?';
|
||||||
|
IS_CS: 'is#';
|
||||||
|
IS_NOT: 'isnot';
|
||||||
|
IS_NOT_IC: 'isnot?';
|
||||||
|
IS_NOT_CS: 'isnot#';
|
||||||
|
|
||||||
|
|
||||||
|
// Assignment operators
|
||||||
|
ASSIGN: '=';
|
||||||
|
PLUS_ASSIGN: '+=';
|
||||||
|
MINUS_ASSIGN: '-=';
|
||||||
|
STAR_ASSIGN: '*=';
|
||||||
|
DIV_ASSIGN: '/=';
|
||||||
|
MOD_ASSIGN: '%=';
|
||||||
|
DOT_ASSIGN: '.=';
|
||||||
|
|
||||||
|
// Escaped chars
|
||||||
|
ESCAPED_QUESTION: '\\?';
|
||||||
|
ESCAPED_SLASH: '\\/';
|
||||||
|
ESCAPED_AMPERSAND: '\\&';
|
||||||
|
|
||||||
|
// Special characters
|
||||||
|
CANCEL: '\u0018';
|
||||||
|
BACKSPACE: '\u0008';
|
||||||
|
ESCAPED_BAR: '\\|' | '\u0016|';
|
||||||
|
BACKSLASH: '\\';
|
||||||
|
|
||||||
|
// Separators
|
||||||
|
NEW_LINE: '\n' | '\r\n';
|
||||||
|
WS: [ \t]+;
|
||||||
|
INLINE_SEPARATOR: '\n' (' ' | '\t')* BACKSLASH -> skip;
|
||||||
|
LUA_CODE: 'lua' WS* '<<' WS* 'EOF' .*? 'EOF' -> skip;
|
||||||
|
LUA_CODE2: 'lua' WS* '<<' WS* 'END' .*? 'END' -> skip;
|
||||||
|
IDEAVIM_IGNORE: ('ideavim' | 'ideaVim' | 'IdeaVim') WS 'ignore' .*? ('ideavim' | 'ideaVim' | 'IdeaVim') WS 'ignore end' -> skip;
|
||||||
|
AUGROUP_SKIP: NEW_LINE (WS|COLON)* AUGROUP .*? AUGROUP WS+ END -> skip;
|
||||||
|
|
||||||
|
// All the other symbols
|
||||||
|
UNICODE_CHAR: '\u0000'..'\uFFFE';
|
||||||
|
EMOJI: [\p{Emoji}];
|