mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
Compare commits
1486 Commits
v0.11.4
...
c333d64663
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c333d64663 | ||
![]() |
b3d29f396d | ||
![]() |
0c0ef489f9 | ||
![]() |
4edeaaa6e2 | ||
![]() |
6eebf30a39 | ||
![]() |
8a2587be23 | ||
![]() |
834e1181da | ||
![]() |
68a2e0ef78 | ||
![]() |
61712cbc3a | ||
![]() |
8a1afac653 | ||
![]() |
dab31a3637 | ||
![]() |
772f1966a3 | ||
![]() |
19f2e5c3eb | ||
![]() |
7a71235399 | ||
![]() |
bc6737250d | ||
![]() |
5edbabdbec | ||
![]() |
118e7e7111 | ||
![]() |
c10e36fc01 | ||
![]() |
a33284c2c0 | ||
![]() |
729111d3a3 | ||
![]() |
2ac00f1350 | ||
![]() |
24020ef2dd | ||
![]() |
9512aac42a | ||
![]() |
a3b1159949 | ||
![]() |
c961361406 | ||
![]() |
bcf952e85f | ||
![]() |
cd7cf4bd16 | ||
![]() |
db1b7f7412 | ||
![]() |
6c3e9b5573 | ||
![]() |
6005fcf671 | ||
![]() |
9269a1da35 | ||
![]() |
117b129378 | ||
![]() |
6014174b71 | ||
![]() |
3586e047e6 | ||
![]() |
b116ed7b12 | ||
![]() |
443278c587 | ||
![]() |
4263ec21c2 | ||
![]() |
c741927883 | ||
![]() |
8f78591f9a | ||
![]() |
8b171852a9 | ||
![]() |
1e1619de83 | ||
![]() |
6a409e0507 | ||
![]() |
e6ba78919c | ||
![]() |
c845f1923d | ||
![]() |
b7124ae768 | ||
![]() |
d07cbb2f42 | ||
![]() |
61217e3618 | ||
![]() |
ad1dfc92a0 | ||
![]() |
5e521c3b5a | ||
![]() |
088ba835ed | ||
![]() |
821bfc02fb | ||
![]() |
516363e6ba | ||
![]() |
5f3d00a5a6 | ||
![]() |
58060c2340 | ||
![]() |
42f244bf18 | ||
![]() |
0e70aa0e86 | ||
![]() |
bccec33f5a | ||
![]() |
b2a136bd67 | ||
![]() |
1f63735f17 | ||
![]() |
76729a2044 | ||
![]() |
b5e20d7dff | ||
![]() |
5a14a2679d | ||
![]() |
40f5115ac4 | ||
![]() |
6018aed92f | ||
![]() |
98407a8b91 | ||
![]() |
e12eca77ee | ||
![]() |
53802da38b | ||
![]() |
62b45b8fe4 | ||
![]() |
7499c9f9a7 | ||
![]() |
a4a690e597 | ||
![]() |
523371b044 | ||
![]() |
0b8a9bde0e | ||
![]() |
810a234978 | ||
![]() |
17601e709f | ||
![]() |
c1fa3c7c37 | ||
![]() |
29c5559ce1 | ||
![]() |
faff3617ba | ||
![]() |
ed40d89d7c | ||
![]() |
963ead29d9 | ||
![]() |
1c0465bec6 | ||
![]() |
6ef996a082 | ||
![]() |
4019d3050d | ||
![]() |
639f9f4cda | ||
![]() |
b9699d5701 | ||
![]() |
eeba0dc2ed | ||
![]() |
586b1b2d9b | ||
![]() |
5d8e870c11 | ||
![]() |
df9ff9cfa8 | ||
![]() |
ec8a0c7340 | ||
![]() |
1ffaaa06c5 | ||
![]() |
7acfad226d | ||
![]() |
92e7d5eaf2 | ||
![]() |
d73cfefed5 | ||
![]() |
12b6f65283 | ||
![]() |
8e48c02061 | ||
![]() |
865a28155e | ||
![]() |
c522cb0e96 | ||
![]() |
9467731865 | ||
![]() |
30dae87de4 | ||
![]() |
a8dad46e1c | ||
![]() |
dc2d4b07a8 | ||
![]() |
e77d15cc5d | ||
![]() |
ed012b817d | ||
![]() |
09964b7ef0 | ||
![]() |
15d3a83999 | ||
![]() |
d06fdecb97 | ||
![]() |
fbaead249b | ||
![]() |
7d53982b7f | ||
![]() |
1fdacbb3e4 | ||
![]() |
049de6f119 | ||
![]() |
848c7a7894 | ||
![]() |
cd2d5de1f9 | ||
![]() |
61b6553ee9 | ||
![]() |
4a1295c626 | ||
![]() |
27bc7dcb01 | ||
![]() |
3d511833ae | ||
![]() |
ba25f3e4d4 | ||
![]() |
3ec63cdab8 | ||
![]() |
701258921e | ||
![]() |
6b936002cc | ||
![]() |
25bc41847e | ||
![]() |
1e20f31aa3 | ||
![]() |
ddae46fba0 | ||
![]() |
1b2a6e0664 | ||
![]() |
f40162ba19 | ||
![]() |
050b04384e | ||
![]() |
2ace4089f8 | ||
![]() |
b3fbc8d6fa | ||
![]() |
052126b77a | ||
![]() |
f363ea8547 | ||
![]() |
960b33a9d8 | ||
![]() |
1d40f67776 | ||
![]() |
37119ad0d2 | ||
![]() |
e4d3812c8b | ||
![]() |
c1f142322b | ||
![]() |
f5cbf11644 | ||
![]() |
2211953266 | ||
![]() |
d8ed43c6a7 | ||
![]() |
4299837b44 | ||
![]() |
7eb9badd93 | ||
![]() |
285c04e2d0 | ||
![]() |
35a7642647 | ||
![]() |
a37e101dc7 | ||
![]() |
7c3e579a90 | ||
![]() |
81d8198bda | ||
![]() |
a7fef170b7 | ||
![]() |
9f5b309d82 | ||
![]() |
98f8224c19 | ||
![]() |
7e450aa383 | ||
![]() |
577f9fa1be | ||
![]() |
5f8d4a248a | ||
![]() |
77860f5418 | ||
![]() |
013af17ed9 | ||
![]() |
c12701d4e1 | ||
![]() |
8d154e5927 | ||
![]() |
7afcfb6c9a | ||
![]() |
e38e65b86c | ||
![]() |
218ff601c4 | ||
![]() |
649bb372f6 | ||
![]() |
bd45e2be63 | ||
![]() |
c26f989b2f | ||
![]() |
38986188ba | ||
![]() |
442f297c63 | ||
![]() |
d19d2b4491 | ||
![]() |
9843573a61 | ||
![]() |
2619a749a5 | ||
![]() |
6f0ef8a5f2 | ||
![]() |
869000e7ce | ||
![]() |
6f904cfef1 | ||
![]() |
7b9512e613 | ||
![]() |
44fdbd6589 | ||
![]() |
b70a6f3f3e | ||
![]() |
35be59cc7b | ||
![]() |
50ceac4054 | ||
![]() |
76a383bb7b | ||
![]() |
c7c3f9fc9c | ||
![]() |
3eab5bd38a | ||
![]() |
e6e1e71abf | ||
![]() |
5e1c35509e | ||
![]() |
dc6cf3add9 | ||
![]() |
a26cdcb20e | ||
![]() |
bc4bddbb21 | ||
![]() |
3c7b698d61 | ||
![]() |
67fede0fc9 | ||
![]() |
7cc07e8383 | ||
![]() |
be5a4851ea | ||
![]() |
f7802dd5d5 | ||
![]() |
b52f9a19b3 | ||
![]() |
09f2c8d8ed | ||
![]() |
e94d8f03b9 | ||
![]() |
e3fd906b61 | ||
![]() |
7048c36ba8 | ||
![]() |
750c350be8 | ||
![]() |
c9b35360ac | ||
![]() |
83f38800e7 | ||
![]() |
36fc266e86 | ||
![]() |
03c953008c | ||
![]() |
d2cdfc413b | ||
![]() |
39af96c8ef | ||
![]() |
82a54a772b | ||
![]() |
d395dc9d38 | ||
![]() |
47e3aecb78 | ||
![]() |
9d85f086d9 | ||
![]() |
22d90217c6 | ||
![]() |
dae79f2b67 | ||
![]() |
f0d8341984 | ||
![]() |
72969f1301 | ||
![]() |
74511a98fd | ||
![]() |
9e8d551b1e | ||
![]() |
1eca030fb2 | ||
![]() |
f79430e2ce | ||
![]() |
77500c5ad5 | ||
![]() |
acff86601e | ||
![]() |
dd828690c7 | ||
![]() |
b337c6e0fc | ||
![]() |
e3913c0fc2 | ||
![]() |
f7e8efd2e9 | ||
![]() |
7a07454867 | ||
![]() |
acc55f6fed | ||
![]() |
a2b0be19bf | ||
![]() |
2c3929624a | ||
![]() |
5f23aaba00 | ||
![]() |
b1e35cbd7b | ||
![]() |
1968029003 | ||
![]() |
fa92a0b9fe | ||
![]() |
5977bdba05 | ||
![]() |
b2828af5b5 | ||
![]() |
fe42c81f2e | ||
![]() |
70bb7999f7 | ||
![]() |
a0d94ac469 | ||
![]() |
1969f685af | ||
![]() |
e7dfbf1343 | ||
![]() |
798cb0f19a | ||
![]() |
36361d6e4a | ||
![]() |
75d38bb844 | ||
![]() |
b1679f0ab6 | ||
![]() |
69cc16d917 | ||
![]() |
ffeb334da0 | ||
![]() |
62f2b10db3 | ||
![]() |
9139c4f90f | ||
![]() |
038eb01b41 | ||
![]() |
7230296bdb | ||
![]() |
c6f0a19206 | ||
![]() |
53ac2ad20a | ||
![]() |
52c2519095 | ||
![]() |
d994be44d7 | ||
![]() |
6502dd43c4 | ||
![]() |
1f7ab25915 | ||
![]() |
7dbf347dda | ||
![]() |
5aaee7d2af | ||
![]() |
e12bfb4c70 | ||
![]() |
5f9f706462 | ||
![]() |
c47a69c1a6 | ||
![]() |
d26db4bfbf | ||
![]() |
d73f2d9657 | ||
![]() |
c04e40d9f4 | ||
![]() |
e40199c6c6 | ||
![]() |
c46641fea1 | ||
![]() |
654cde369d | ||
![]() |
cc25cd2cb7 | ||
![]() |
bc0b3f271c | ||
![]() |
5b1b46ea5a | ||
![]() |
79c8159f41 | ||
![]() |
b4c092a092 | ||
![]() |
851a622806 | ||
![]() |
5b3606b2c4 | ||
![]() |
60dca47ae4 | ||
![]() |
a3921d2be6 | ||
![]() |
72d3ffd716 | ||
![]() |
0fa81578af | ||
![]() |
b869cf8ddc | ||
![]() |
cba2f65ee4 | ||
![]() |
820fb89172 | ||
![]() |
7ae8860674 | ||
![]() |
b95413f601 | ||
![]() |
474c477134 | ||
![]() |
d632ffa243 | ||
![]() |
2a267d1cbf | ||
![]() |
758e6db06c | ||
![]() |
a9a4c271b1 | ||
![]() |
a5c598871b | ||
![]() |
54bfd0de4f | ||
![]() |
c789d79966 | ||
![]() |
ecded994c1 | ||
![]() |
7ed8cbd095 | ||
![]() |
40aef0d02e | ||
![]() |
2ef48fc65c | ||
![]() |
9910445125 | ||
![]() |
78f4994627 | ||
![]() |
39e402caa5 | ||
![]() |
e23794b090 | ||
![]() |
f7af0cff35 | ||
![]() |
26cc42e426 | ||
![]() |
22df649210 | ||
![]() |
93f5bd0caf | ||
![]() |
3f416ef524 | ||
![]() |
6e27200901 | ||
![]() |
52a596b0aa | ||
![]() |
2e62f3576f | ||
![]() |
d3bea4ace9 | ||
![]() |
89a72f11e5 | ||
![]() |
6721128cc8 | ||
![]() |
ed73ed8283 | ||
![]() |
8200223ee7 | ||
![]() |
267bbe64cb | ||
![]() |
a203961535 | ||
![]() |
3f34f083db | ||
![]() |
28e2a5c151 | ||
![]() |
1ee18b4061 | ||
![]() |
1240d29f8f | ||
![]() |
94d09d6627 | ||
![]() |
1af5ec5b51 | ||
![]() |
68eece8b84 | ||
![]() |
c3a4d12529 | ||
![]() |
b79ff967ac | ||
![]() |
807a65b2da | ||
![]() |
1256daeead | ||
![]() |
15d57ab0ba | ||
![]() |
029b7a149f | ||
![]() |
dc3a30cfbb | ||
![]() |
c81dc320b0 | ||
![]() |
56a4ef3c21 | ||
![]() |
dc67ba948e | ||
![]() |
cf9b36f3d9 | ||
![]() |
7a051a4c38 | ||
![]() |
5151f635ca | ||
![]() |
d08b265111 | ||
![]() |
628d569a59 | ||
![]() |
dff78f580d | ||
![]() |
afebbd0f34 | ||
![]() |
b4ba27c238 | ||
![]() |
8a7bfdc079 | ||
![]() |
af5ac7c7ea | ||
![]() |
5de2ec76a3 | ||
![]() |
0a113013fb | ||
![]() |
e4a100a1e1 | ||
![]() |
1f7432a272 | ||
![]() |
e512efe369 | ||
![]() |
6190b6bc1d | ||
![]() |
3e655d3e42 | ||
![]() |
35af766de6 | ||
![]() |
54b8c99e51 | ||
![]() |
0dcdd65dcc | ||
![]() |
61c4a6b3a9 | ||
![]() |
95dfb063da | ||
![]() |
4fe51dfdae | ||
![]() |
1685c44dd4 | ||
![]() |
e28aee0c72 | ||
![]() |
d6704148bc | ||
![]() |
c93091395b | ||
![]() |
d591275db7 | ||
![]() |
9377db2545 | ||
![]() |
8b5d8dfc73 | ||
![]() |
9fc985bc98 | ||
![]() |
4fadc21e38 | ||
![]() |
0bef1c88f3 | ||
![]() |
9813c00dd3 | ||
![]() |
1d2d6e31a7 | ||
![]() |
05a83265f9 | ||
![]() |
3a36df9b13 | ||
![]() |
b0e8b0a35f | ||
![]() |
7c38f428f4 | ||
![]() |
9a5b3a39f3 | ||
![]() |
371aa1c566 | ||
![]() |
1d8e9b5d07 | ||
![]() |
ea2d226df6 | ||
![]() |
8ee82da3cf | ||
![]() |
2795df7aac | ||
![]() |
22d1fb8c01 | ||
![]() |
bbc368dfce | ||
![]() |
85bd0b6a03 | ||
![]() |
f2d92ba6ca | ||
![]() |
b79ed66e4a | ||
![]() |
6a97eb332a | ||
![]() |
4765d4e059 | ||
![]() |
00c2e7d89c | ||
![]() |
1e81b54075 | ||
![]() |
fadbc0e717 | ||
![]() |
441d222c0d | ||
![]() |
c3991b8ef4 | ||
![]() |
2495015455 | ||
![]() |
b6b793634a | ||
![]() |
c556c6677b | ||
![]() |
6831c7de65 | ||
![]() |
4962c60c6f | ||
![]() |
5400df0f7f | ||
![]() |
0f9b5dd0b4 | ||
![]() |
b91613f42c | ||
![]() |
14cafbcc85 | ||
![]() |
8dfad04ce9 | ||
![]() |
8f75c0b586 | ||
![]() |
e5c2ce5905 | ||
![]() |
c5167ffc18 | ||
![]() |
db1542af3d | ||
![]() |
f21ada30e1 | ||
![]() |
b21c357b9c | ||
![]() |
46648c3867 | ||
![]() |
3a140ddbc6 | ||
![]() |
10a0c59487 | ||
![]() |
73943eb0d1 | ||
![]() |
f2691199fa | ||
![]() |
26bbeadda3 | ||
![]() |
f5829957f2 | ||
![]() |
586e6d427a | ||
![]() |
a3cfdcebb9 | ||
![]() |
538c945fdf | ||
![]() |
d7050d6e39 | ||
![]() |
9df9d3af3b | ||
![]() |
fd5d04fbff | ||
![]() |
1de2a03fc7 | ||
![]() |
1255a8d88d | ||
![]() |
995bc31eaf | ||
![]() |
7631302ad6 | ||
![]() |
4fe6fcc5b7 | ||
![]() |
77c6cae25b | ||
![]() |
ad0c21a445 | ||
![]() |
2efc84d005 | ||
![]() |
5671b61327 | ||
![]() |
4f0ab9877b | ||
![]() |
e0d179561d | ||
![]() |
9d1333a385 | ||
![]() |
1b6848c299 | ||
![]() |
0d0655f725 | ||
![]() |
4a4e6a792a | ||
![]() |
be35864318 | ||
![]() |
436ae1d23e | ||
![]() |
a08d6a8ac1 | ||
![]() |
e6ce067f02 | ||
![]() |
8bf99ddbac | ||
![]() |
e946951f6a | ||
![]() |
1c6ddd9a5f | ||
![]() |
fcec1610e7 | ||
![]() |
8bccd07972 | ||
![]() |
4195b82ec9 | ||
![]() |
fa648731ec | ||
![]() |
694f634556 | ||
![]() |
83818b885a | ||
![]() |
ace254c9ff | ||
![]() |
5cfdd4d8b9 | ||
![]() |
9789a3b854 | ||
![]() |
112092271b | ||
![]() |
d4c8e8df1c | ||
![]() |
3eb597c999 | ||
![]() |
73987a4301 | ||
![]() |
a945686444 | ||
![]() |
12276832ab | ||
![]() |
7bf04bc01f | ||
![]() |
9f16b598f9 | ||
![]() |
f487ae90cf | ||
![]() |
96ec4db3e9 | ||
![]() |
7cd5356a6f | ||
![]() |
444a8b3ec6 | ||
![]() |
3e7f5d95aa | ||
![]() |
73fbc693b5 | ||
![]() |
89b946aa87 | ||
![]() |
5c4f9b05fa | ||
![]() |
7e8aa0585e | ||
![]() |
a8d9f3331e | ||
![]() |
7ac4cbcd2e | ||
![]() |
4778a4c201 | ||
![]() |
815916b450 | ||
![]() |
f3a54e7ccf | ||
![]() |
430be9d01d | ||
![]() |
3812cb1cd1 | ||
![]() |
2422fbdd5f | ||
![]() |
eb5b4b9e57 | ||
![]() |
d2098057a7 | ||
![]() |
34fbfa3586 | ||
![]() |
f1babb322b | ||
![]() |
8c6ea76ebc | ||
![]() |
d4074b812d | ||
![]() |
7f5b5d34cf | ||
![]() |
9e968635ef | ||
![]() |
4f3aa7bafb | ||
![]() |
7a69fefdb9 | ||
![]() |
c3e2926f17 | ||
![]() |
e78c877688 | ||
![]() |
58df501913 | ||
![]() |
00f8f94d5b | ||
![]() |
54cde0674b | ||
![]() |
9809ce8b47 | ||
![]() |
68e316e3f9 | ||
![]() |
7bd4dfd209 | ||
![]() |
4745270bf1 | ||
![]() |
213360c389 | ||
![]() |
5803994a1c | ||
![]() |
e644038f06 | ||
![]() |
7f18811668 | ||
![]() |
fccd016a0f | ||
![]() |
e65c0a0810 | ||
![]() |
fb0dc825e9 | ||
![]() |
7526fb449d | ||
![]() |
8aed423072 | ||
![]() |
977e91b424 | ||
![]() |
76f6868e0a | ||
![]() |
840cdb9589 | ||
![]() |
3a3484be29 | ||
![]() |
3c9484b550 | ||
![]() |
88774965e5 | ||
![]() |
96aef50624 | ||
![]() |
5fe310c5e6 | ||
![]() |
ef0ec7edac | ||
![]() |
db7c2acbc6 | ||
![]() |
435f03ee10 | ||
![]() |
bb6422f1ad | ||
![]() |
28b7c2df52 | ||
![]() |
f68a5c40f0 | ||
![]() |
f576b59a09 | ||
![]() |
bf9d3e4bf8 | ||
![]() |
d88bebfbc7 | ||
![]() |
27daeb0d68 | ||
![]() |
ed8b022633 | ||
![]() |
842ca1fd5c | ||
![]() |
62822d750d | ||
![]() |
5fd386a893 | ||
![]() |
0c973bf442 | ||
![]() |
d523750de0 | ||
![]() |
c3c8d25293 | ||
![]() |
2031287e93 | ||
![]() |
0d9bf5b89f | ||
![]() |
4310f3f580 | ||
![]() |
d73788fad2 | ||
![]() |
3177841bdf | ||
![]() |
8d5452c46d | ||
![]() |
55e3a75217 | ||
![]() |
5973328eda | ||
![]() |
6fd2a3040f | ||
![]() |
2e2ac49c57 | ||
![]() |
86a2ebd5fe | ||
![]() |
18e0301e1f | ||
![]() |
12689c73d8 | ||
![]() |
957093da0d | ||
![]() |
580b8cfac7 | ||
![]() |
4f141dca8c | ||
![]() |
09f9d72c24 | ||
![]() |
cf5506f0fd | ||
![]() |
5335d9991f | ||
![]() |
8a4977e286 | ||
![]() |
11e967d5af | ||
![]() |
025c070312 | ||
![]() |
9c04eb02ad | ||
![]() |
6ebcb4a4d6 | ||
![]() |
8fe4e120a2 | ||
![]() |
55f003671d | ||
![]() |
728b3e3d50 | ||
![]() |
0ea7a65299 | ||
![]() |
518f95e27e | ||
![]() |
85e6feedb0 | ||
![]() |
887255362f | ||
![]() |
c3f35a38fe | ||
![]() |
46727a7feb | ||
![]() |
9a44bbd574 | ||
![]() |
dd707246fd | ||
![]() |
cc83854036 | ||
![]() |
023f157a60 | ||
![]() |
3564e62426 | ||
![]() |
3bf27b2c74 | ||
![]() |
d574f9479d | ||
![]() |
11f8e8eb63 | ||
![]() |
7138cdaef8 | ||
![]() |
d9465e984b | ||
![]() |
c30b93db93 | ||
![]() |
0c02c9c70b | ||
![]() |
52b9bab340 | ||
![]() |
3342aead1d | ||
![]() |
285ea2525f | ||
![]() |
e34e2289c2 | ||
![]() |
cbfc3d1cdc | ||
![]() |
d21b8c949a | ||
![]() |
cf0f90fe14 | ||
![]() |
3694fcec28 | ||
![]() |
16001b4d84 | ||
![]() |
bb75610d99 | ||
![]() |
c48dea20f5 | ||
![]() |
5db833b475 | ||
![]() |
f348c0ebba | ||
![]() |
c925e7b8ba | ||
![]() |
bfffe0d214 | ||
![]() |
17ecb2b988 | ||
![]() |
14d8d11671 | ||
![]() |
eef62e815d | ||
![]() |
f01419f3d5 | ||
![]() |
715c28d67f | ||
![]() |
ac75de0d2a | ||
![]() |
a5e582dab6 | ||
![]() |
0a6a73fd25 | ||
![]() |
fc1be07d28 | ||
![]() |
0a14ac3261 | ||
![]() |
18cfbf8fb2 | ||
![]() |
da42f99eb4 | ||
![]() |
535e292436 | ||
![]() |
168bf0024e | ||
![]() |
94f44d58fd | ||
![]() |
4eebc46930 | ||
![]() |
e91224bfaa | ||
![]() |
807bc00dd6 | ||
![]() |
38aac21083 | ||
![]() |
f731766474 | ||
![]() |
99873296be | ||
![]() |
66f02ee1fe | ||
![]() |
af6b3d6fec | ||
![]() |
773075b2bc | ||
![]() |
649ff924d9 | ||
![]() |
4034476dd3 | ||
![]() |
d6d1bfd20d | ||
![]() |
aeb8bca12d | ||
![]() |
561021bacd | ||
![]() |
ed7ff848a0 | ||
![]() |
f7c939fa7a | ||
![]() |
2f95abddfa | ||
![]() |
1c52e90cd5 | ||
![]() |
63a7b92e58 | ||
![]() |
331de6afa6 | ||
![]() |
10a03e83e3 | ||
![]() |
bff7d3fd9f | ||
![]() |
f1f106be3d | ||
![]() |
c752016976 | ||
![]() |
4ee2e365a5 | ||
![]() |
f2988e05db | ||
![]() |
bfe42c84de | ||
![]() |
64753b5c37 | ||
![]() |
0b91e9f83b | ||
![]() |
e518666f1d | ||
![]() |
2b4c1127ad | ||
![]() |
6005bc68b2 | ||
![]() |
f0c0c24ed7 | ||
![]() |
5d06eade25 | ||
![]() |
76de3e2d07 | ||
![]() |
3eaa6c5a66 | ||
![]() |
b40e658717 | ||
![]() |
f0757ee590 | ||
![]() |
e5dae58704 | ||
![]() |
c730374d44 | ||
![]() |
731e616a79 | ||
![]() |
4369d7d9a7 | ||
![]() |
0694ca8822 | ||
![]() |
684be736c1 | ||
![]() |
5ae41ddde3 | ||
![]() |
efd0fa55c8 | ||
![]() |
25000be845 | ||
![]() |
5871d26779 | ||
![]() |
6b6a4518c2 | ||
![]() |
7f3249fa0d | ||
![]() |
69c379dc44 | ||
![]() |
92883b918c | ||
![]() |
40c61bf205 | ||
![]() |
6942dec9b2 | ||
![]() |
fb5a51e775 | ||
![]() |
835f11595f | ||
![]() |
a5c55d200b | ||
![]() |
462f7aaa8e | ||
![]() |
534ec8d447 | ||
![]() |
30f650420b | ||
![]() |
233014f3ed | ||
![]() |
69ef85a533 | ||
![]() |
cfb4d3d2f2 | ||
![]() |
ee2fc31b36 | ||
![]() |
0980617c0d | ||
![]() |
d0aedd36df | ||
![]() |
cacb4ceeb4 | ||
![]() |
927dc3c2c4 | ||
![]() |
528381587b | ||
![]() |
0dc900d744 | ||
![]() |
150513a163 | ||
![]() |
487112d674 | ||
![]() |
2379fb053a | ||
![]() |
255f313cf6 | ||
![]() |
f038213617 | ||
![]() |
fb8dba413f | ||
![]() |
8ed6f00ab0 | ||
![]() |
0456d75517 | ||
![]() |
3594c213a7 | ||
![]() |
8e17b72094 | ||
![]() |
5cf135f9a0 | ||
![]() |
32f30c4874 | ||
![]() |
aa8c86e8f3 | ||
![]() |
237bb9cb59 | ||
![]() |
cb2367a1e2 | ||
![]() |
c8e54bf49d | ||
![]() |
3b85046ed5 | ||
![]() |
8af2aea24f | ||
![]() |
17c18efbe5 | ||
![]() |
b3c78f4b3c | ||
![]() |
2c9d21f722 | ||
![]() |
286371b4d2 | ||
![]() |
496691f985 | ||
![]() |
e74753a221 | ||
![]() |
006361fc6b | ||
![]() |
1bf9a07b3e | ||
![]() |
6976ff57dd | ||
![]() |
cd06e0c9d6 | ||
![]() |
ae0981070e | ||
![]() |
3e984cf02b | ||
![]() |
5647b45e69 | ||
![]() |
24bb110588 | ||
![]() |
35756022cb | ||
![]() |
492ea28612 | ||
![]() |
9f99bf48ea | ||
![]() |
1d7823451e | ||
![]() |
6ad2a13054 | ||
![]() |
576e8f62c2 | ||
![]() |
b2722181b0 | ||
![]() |
5fe582448c | ||
![]() |
8cfb993fdf | ||
![]() |
b92e3889fe | ||
![]() |
4b2c2eb120 | ||
![]() |
00ad477419 | ||
![]() |
29f2cb89f0 | ||
![]() |
5ea6a022c0 | ||
![]() |
5046ef4c8f | ||
![]() |
0d658660c2 | ||
![]() |
c7f38e3bc8 | ||
![]() |
4367441213 | ||
![]() |
1deba926c4 | ||
![]() |
17571bc4c0 | ||
![]() |
d21e2463fd | ||
![]() |
76d213efbe | ||
![]() |
8001276bd0 | ||
![]() |
1d5b3b5b4c | ||
![]() |
9ec6c19c67 | ||
![]() |
76f76fb083 | ||
![]() |
3e30323135 | ||
![]() |
29c8dabd41 | ||
![]() |
1ede826e04 | ||
![]() |
beee60f3a0 | ||
![]() |
90b682891d | ||
![]() |
82d0883c2d | ||
![]() |
7486c2f6aa | ||
![]() |
f99e3a8a2a | ||
![]() |
a9b8a8dc6c | ||
![]() |
ac12dc49cc | ||
![]() |
d86d4bacc1 | ||
![]() |
221b6ddf1c | ||
![]() |
b8ee354f12 | ||
![]() |
dc05598d02 | ||
![]() |
66e4784f5a | ||
![]() |
5f00e6adaf | ||
![]() |
3a2ac2300b | ||
![]() |
47df8f5a4b | ||
![]() |
6bee2f686f | ||
![]() |
6a71239cd5 | ||
![]() |
de87ceb3be | ||
![]() |
966b1da183 | ||
![]() |
7aafbca510 | ||
![]() |
719c7e2312 | ||
![]() |
8cd0ef06bb | ||
![]() |
b1aed2b40a | ||
![]() |
677a50bb26 | ||
![]() |
bac133e4b6 | ||
![]() |
fb7a234f01 | ||
![]() |
37d6ac8a15 | ||
![]() |
1abcd9fe28 | ||
![]() |
79ce71430f | ||
![]() |
8ea18de959 | ||
![]() |
612f8e7c9e | ||
![]() |
cbc9d9b9c7 | ||
![]() |
5075043823 | ||
![]() |
ac772706cc | ||
![]() |
b5aef05b8f | ||
![]() |
228ff6e547 | ||
![]() |
c2aa5fd915 | ||
![]() |
2dba5abcb2 | ||
![]() |
b98eefd803 | ||
![]() |
93925fe020 | ||
![]() |
4387c26691 | ||
![]() |
b7cb7fe51c | ||
![]() |
5394320a67 | ||
![]() |
2f167c53ac | ||
![]() |
2c80b05cbd | ||
![]() |
bcba067dc2 | ||
![]() |
7a58cf4b96 | ||
![]() |
78e2f62516 | ||
![]() |
4fb36ea95f | ||
![]() |
72f4bb9ae8 | ||
![]() |
bcfc22853a | ||
![]() |
cb4559bc32 | ||
![]() |
d75ffa5934 | ||
![]() |
a5f236291c | ||
![]() |
e876a739ee | ||
![]() |
2f0fbdaa48 | ||
![]() |
2d980e37c8 | ||
![]() |
336b46a879 | ||
![]() |
8fadb80b3a | ||
![]() |
76d0206342 | ||
![]() |
ca9689858d | ||
![]() |
cbaca9fee7 | ||
![]() |
6f632a8615 | ||
![]() |
811e12cebc | ||
![]() |
680d3770b1 | ||
![]() |
f2e60d000e | ||
![]() |
58d85cd03d | ||
![]() |
d2dad30898 | ||
![]() |
2b79d9ba1a | ||
![]() |
8b41df185c | ||
![]() |
775e845d59 | ||
![]() |
e21c54000e | ||
![]() |
00bec1fd90 | ||
![]() |
03bfc4e8d3 | ||
![]() |
a1fc8bc17c | ||
![]() |
a118597290 | ||
![]() |
21a2411763 | ||
![]() |
52c61d9690 | ||
![]() |
faae1e72a2 | ||
![]() |
96a0e5f265 | ||
![]() |
c8c78b531b | ||
![]() |
af82f36108 | ||
![]() |
22389159f5 | ||
![]() |
bf1d4e9793 | ||
![]() |
3b6084ddf4 | ||
![]() |
4c333fdbb7 | ||
![]() |
744674900f | ||
![]() |
99e6294819 | ||
![]() |
cb036cae5f | ||
![]() |
e5c5b563ec | ||
![]() |
3165e94a64 | ||
![]() |
9f505b4d0f | ||
![]() |
60d0b7d0c3 | ||
![]() |
552983515f | ||
![]() |
4e71d3bfab | ||
![]() |
a9f544b712 | ||
![]() |
6171ab7f4e | ||
![]() |
f89381e05c | ||
![]() |
2b21c9c23f | ||
![]() |
b6b35cb557 | ||
![]() |
1c417b565e | ||
![]() |
5e470c7af5 | ||
![]() |
b16dc698cf | ||
![]() |
a5bbdbb5d5 | ||
![]() |
038fb30ece | ||
![]() |
5e4700152b | ||
![]() |
03832842d5 | ||
![]() |
f577bb024e | ||
![]() |
442dade5be | ||
![]() |
7e393ff4f2 | ||
![]() |
dd9ac565d8 | ||
![]() |
97ca92f9dd | ||
![]() |
3d1f907912 | ||
![]() |
533cc0ab35 | ||
![]() |
9641ad9369 | ||
![]() |
3991f14621 | ||
![]() |
eeacd7bd71 | ||
![]() |
eb10852804 | ||
![]() |
ee84518b94 | ||
![]() |
049877d379 | ||
![]() |
304a9baebd | ||
![]() |
aa4fa24963 | ||
![]() |
9c9c7ae30f | ||
![]() |
525c02a89f | ||
![]() |
9bfd0162dc | ||
![]() |
bec1449cc5 | ||
![]() |
2411f924a3 | ||
![]() |
eeff6ca8ff | ||
![]() |
13aec582b4 | ||
![]() |
857ff5cae9 | ||
![]() |
b6acf6112b | ||
![]() |
c249389adb | ||
![]() |
7651c43252 | ||
![]() |
0af6d6ff5e | ||
![]() |
33b0a004eb | ||
![]() |
5e83d0f5ad | ||
![]() |
963308439a | ||
![]() |
86835b3db3 | ||
![]() |
236243029d | ||
![]() |
5fd03508aa | ||
![]() |
06f07a104b | ||
![]() |
52991d8728 | ||
![]() |
981d4ba45e | ||
![]() |
5cfbc35aa8 | ||
![]() |
80753332d1 | ||
![]() |
ff95d7ff9a | ||
![]() |
b95189b7e3 | ||
![]() |
84c7785546 | ||
![]() |
b77666e6f9 | ||
![]() |
7384cf015e | ||
![]() |
4091f2c740 | ||
![]() |
7a8b0cd0f8 | ||
![]() |
f72c13341a | ||
![]() |
0471cc7595 | ||
![]() |
41179a6bc1 | ||
![]() |
7082367b3a | ||
![]() |
60b866049c | ||
![]() |
2763d06100 | ||
![]() |
11ae879ebd | ||
![]() |
5ebaf83256 | ||
![]() |
eb6ca14248 | ||
![]() |
d29b800515 | ||
![]() |
7ed8e96994 | ||
![]() |
ade64c3ca3 | ||
![]() |
9e81408b69 | ||
![]() |
9d5eb3eda5 | ||
![]() |
756751afa3 | ||
![]() |
b28bbee539 | ||
![]() |
f82219c490 | ||
![]() |
532610388b | ||
![]() |
cc264d51ab | ||
![]() |
6c4ddf607f | ||
![]() |
03933fe4c0 | ||
![]() |
f2373a89d7 | ||
![]() |
a4f318574a | ||
![]() |
8af28ab9cb | ||
![]() |
70697417c4 | ||
![]() |
d22fcf2917 | ||
![]() |
85d33514f9 | ||
![]() |
3828856233 | ||
![]() |
8defe1afb2 | ||
![]() |
66dddd8b51 | ||
![]() |
c4e52d604c | ||
![]() |
8c5bd841ed | ||
![]() |
092e49d020 | ||
![]() |
a2daa3c0c0 | ||
![]() |
fbf5fbacc2 | ||
![]() |
e35a7d4782 | ||
![]() |
5e64d92411 | ||
![]() |
ba1cc9e10c | ||
![]() |
aa9fd08034 | ||
![]() |
c973c7ae6f | ||
![]() |
a6e2c22347 | ||
![]() |
bd01bd6564 | ||
![]() |
4db58f78b4 | ||
![]() |
52868977ae | ||
![]() |
8b9500c886 | ||
![]() |
06043af27d | ||
![]() |
af947f0107 | ||
![]() |
e25b99c5b6 | ||
![]() |
c4501e98f2 | ||
![]() |
a96665cf48 | ||
![]() |
8a207b3e19 | ||
![]() |
baabc35987 | ||
![]() |
a59b052857 | ||
![]() |
c9d8468020 | ||
![]() |
9784bc1346 | ||
![]() |
abb40ecedd | ||
![]() |
7c2b4a0eaf | ||
![]() |
6ce2877327 | ||
![]() |
071dcab68f | ||
![]() |
f791ae82e5 | ||
![]() |
41c850e2c8 | ||
![]() |
079e7d2b11 | ||
![]() |
153a910897 | ||
![]() |
f0fb6d448a | ||
![]() |
927927e143 | ||
![]() |
27bb814cb1 | ||
![]() |
62ba6e8a76 | ||
![]() |
fed9069b8d | ||
![]() |
2d4b028d02 | ||
![]() |
c81af9428c | ||
![]() |
0412527a40 | ||
![]() |
272e041780 | ||
![]() |
322a6d305d | ||
![]() |
172a90c245 | ||
![]() |
7077c59295 | ||
![]() |
2e0158650a | ||
![]() |
19efabafc5 | ||
![]() |
dd43eb445a | ||
![]() |
cd9d8469b2 | ||
![]() |
5ad01184f3 | ||
![]() |
849e24f3cd | ||
![]() |
14631e2264 | ||
![]() |
dbe17da120 | ||
![]() |
1524868711 | ||
![]() |
8d397fa458 | ||
![]() |
2045e9700c | ||
![]() |
dfad613813 | ||
![]() |
dc6fc11b87 | ||
![]() |
dc6885dc24 | ||
![]() |
3a35fdc347 | ||
![]() |
a87aa68ed0 | ||
![]() |
23c214ed4a | ||
![]() |
5661f74ab2 | ||
![]() |
ba237ce96c | ||
![]() |
913e4c6010 | ||
![]() |
4a6f017bc1 | ||
![]() |
4eed85f9bd | ||
![]() |
9a322f8103 | ||
![]() |
81bb7613f9 | ||
![]() |
8e8f4523c6 | ||
![]() |
f40e140083 | ||
![]() |
99384fcd9c | ||
![]() |
ec5f054dc9 | ||
![]() |
6af1b7e5e8 | ||
![]() |
3659058e80 | ||
![]() |
9d1996ac61 | ||
![]() |
37cac18787 | ||
![]() |
82027fd6bd | ||
![]() |
6e3eb6663e | ||
![]() |
1be2fdb910 | ||
![]() |
469541c415 | ||
![]() |
2fda267faf | ||
![]() |
763e7428e2 | ||
![]() |
142f914089 | ||
![]() |
70eb416459 | ||
![]() |
17e13ce3b6 | ||
![]() |
f87b6230f1 | ||
![]() |
6b9665a507 | ||
![]() |
f2aec4bc05 | ||
![]() |
d25eb246ef | ||
![]() |
4d56dc43c0 | ||
![]() |
b0bb3cccf9 | ||
![]() |
2bfb12ef46 | ||
![]() |
570e62d0f9 | ||
![]() |
4fae013a21 | ||
![]() |
40b64e9100 | ||
![]() |
cc78f88201 | ||
![]() |
a62e55d407 | ||
![]() |
d539a952da | ||
![]() |
e4c4d672b5 | ||
![]() |
cc6ee59f5a | ||
![]() |
2f24ae8de4 | ||
![]() |
c681336e3c | ||
![]() |
e5665754d1 | ||
![]() |
e01f196e44 | ||
![]() |
238e1d6ecc | ||
![]() |
69d04ee99f | ||
![]() |
d04cbb65b9 | ||
![]() |
9c0afc8873 | ||
![]() |
7369f80b19 | ||
![]() |
ef5c5dc99b | ||
![]() |
23bf4c0531 | ||
![]() |
2c07428966 | ||
![]() |
d95b0a5396 | ||
![]() |
05dab80d8d | ||
![]() |
4b3a9ac413 | ||
![]() |
59c45b22d9 | ||
![]() |
73e7e7631c | ||
![]() |
1889c351fd | ||
![]() |
a2c3591720 | ||
![]() |
1826ad16af | ||
![]() |
de45b8e275 | ||
![]() |
bee45fc0e7 | ||
![]() |
8605f5655b | ||
![]() |
f38f92931a | ||
![]() |
44a6e5ea99 | ||
![]() |
1c96b72dfa | ||
![]() |
1d9990daac | ||
![]() |
9b11746d80 | ||
![]() |
cb12c8fa47 | ||
![]() |
1bfb8dd338 | ||
![]() |
db702782e0 | ||
![]() |
c2d218d0c6 | ||
![]() |
e56292071a | ||
![]() |
302e59f734 | ||
![]() |
6adf48b66d | ||
![]() |
7e787f6a4f | ||
![]() |
3121e02ae0 | ||
![]() |
15d31fe7a6 | ||
![]() |
6b955af875 | ||
![]() |
ab5c15610f | ||
![]() |
50c200fcd4 | ||
![]() |
ee1d389fa6 | ||
![]() |
7c43f8e433 | ||
![]() |
d976834864 | ||
![]() |
1b8ae4336d | ||
![]() |
2f2cba24f9 | ||
![]() |
6dee1672cc | ||
![]() |
27311b0b5c | ||
![]() |
186851b1bd | ||
![]() |
d8621a53ac | ||
![]() |
45e9054813 | ||
![]() |
ac67098998 | ||
![]() |
2aa7948266 | ||
![]() |
fb59188b6d | ||
![]() |
f5b5f2095e | ||
![]() |
a81d2b6703 | ||
![]() |
8707ec2644 | ||
![]() |
db2b774a16 | ||
![]() |
c65817774d | ||
![]() |
8d75910ef9 | ||
![]() |
9efdd4fe98 | ||
![]() |
1e7406fa38 | ||
![]() |
912388f517 | ||
![]() |
2d75ea6afe | ||
![]() |
1ad9cdd403 | ||
![]() |
40351bbbbe | ||
![]() |
0862c1036a | ||
![]() |
df345503eb | ||
![]() |
0402f5a76b | ||
![]() |
3268f51d20 | ||
![]() |
d4ecfc4234 | ||
![]() |
ba2a5a7787 | ||
![]() |
72ec410134 | ||
![]() |
fc2dee1736 | ||
![]() |
af4f7f1618 | ||
![]() |
8f5bd569c5 | ||
![]() |
5c15df449a | ||
![]() |
91e116f3a6 | ||
![]() |
cb2ca54331 | ||
![]() |
f1295fe76f | ||
![]() |
921f8b0df7 | ||
![]() |
627c648252 | ||
![]() |
2c1f5a6aa5 | ||
![]() |
9274532615 | ||
![]() |
b877aa34cf | ||
![]() |
047a10bfde | ||
![]() |
8305af9bd2 | ||
![]() |
6256adde2f | ||
![]() |
b2a5105c66 | ||
![]() |
d0867574bd | ||
![]() |
902b689c4d | ||
![]() |
403fcacfc1 | ||
![]() |
03d378fda6 | ||
![]() |
2e35161fa1 | ||
![]() |
94bc7f47bf | ||
![]() |
f048298e9a | ||
![]() |
6b233cd1a1 | ||
![]() |
5d1fd4aca5 | ||
![]() |
adbd33027f | ||
![]() |
862e676efc | ||
![]() |
5a2edc483d | ||
![]() |
34c769dd89 | ||
![]() |
39a5b7f239 | ||
![]() |
c916bdf329 | ||
![]() |
8d6f016345 | ||
![]() |
53b41ec7c2 | ||
![]() |
da3eeb4b32 | ||
![]() |
074a6abd55 | ||
![]() |
0741d2520d | ||
![]() |
3c7c824bdc | ||
![]() |
4b5364b423 | ||
![]() |
1fb0126a08 | ||
![]() |
2c1c0b7af5 | ||
![]() |
da401ca25b | ||
![]() |
1f004970f0 | ||
![]() |
ce8b755a86 | ||
![]() |
dd71a21463 | ||
![]() |
0b3c76502c | ||
![]() |
65a4c8f3ca | ||
![]() |
abc96ba0ce | ||
![]() |
d1fed989f2 | ||
![]() |
d567f899ef | ||
![]() |
97a6259442 | ||
![]() |
edc8e9f40a | ||
![]() |
4bc7bac884 | ||
![]() |
fae4abd2f4 | ||
![]() |
b38525f65c | ||
![]() |
ad48cccaa8 | ||
![]() |
71f3a9c590 | ||
![]() |
6577d72d81 | ||
![]() |
f27fb737ce | ||
![]() |
0015a105ca | ||
![]() |
272dba7f07 | ||
![]() |
f02484118c | ||
![]() |
0ab0cdb2da | ||
![]() |
99e754ae02 | ||
![]() |
08c484f2ca | ||
![]() |
9bbbeb60e3 | ||
![]() |
c35dde03c8 | ||
![]() |
ffb93d9883 | ||
![]() |
e7e665b489 | ||
![]() |
c489b5a3e3 | ||
![]() |
7692a62b75 | ||
![]() |
d107375f0c | ||
![]() |
afcc4e95d5 | ||
![]() |
c64cada12e | ||
![]() |
d75410b091 | ||
![]() |
43f3c4a48f | ||
![]() |
bd413a2f55 | ||
![]() |
317a897c46 | ||
![]() |
ce097c5091 | ||
![]() |
07a207a5f1 | ||
![]() |
644c618825 | ||
![]() |
36dbd2686f | ||
![]() |
1f503ac7c0 | ||
![]() |
52a4bc4548 | ||
![]() |
a6591950f6 | ||
![]() |
71455173b4 | ||
![]() |
82b844fefe | ||
![]() |
181df60533 | ||
![]() |
63323a9c81 | ||
![]() |
b98aefc584 | ||
![]() |
ef16a02a76 | ||
![]() |
e991133058 | ||
![]() |
86b34ad073 | ||
![]() |
a167800f1c | ||
![]() |
923efaea28 | ||
![]() |
c2fc867843 | ||
![]() |
31e31273bc | ||
![]() |
fcabbc2283 | ||
![]() |
d6fffe6b32 | ||
![]() |
66339e0641 | ||
![]() |
c1d21492a6 | ||
![]() |
2c3488c52e | ||
![]() |
1999c4cdc1 | ||
![]() |
dd18ab1691 | ||
![]() |
e7410048fa | ||
![]() |
d927a87ed6 | ||
![]() |
f486f1742e | ||
![]() |
8315697449 | ||
![]() |
e45ec5a852 | ||
![]() |
e324ab2b6b | ||
![]() |
342974773c | ||
![]() |
9e93bfdb5f | ||
![]() |
8090dcf494 | ||
![]() |
766cd01ff2 | ||
![]() |
d01b2611a6 | ||
![]() |
d9353bd442 | ||
![]() |
06613989a6 | ||
![]() |
1fed4412e4 | ||
![]() |
9e450000d3 | ||
![]() |
4ddd31de14 | ||
![]() |
533ce0e807 | ||
![]() |
7d569abb20 | ||
![]() |
1670fbee0f | ||
![]() |
276860b538 | ||
![]() |
18e8839c80 | ||
![]() |
8495d96238 | ||
![]() |
9ff1239634 | ||
![]() |
ca47cc39f8 | ||
![]() |
ac8ae1596c | ||
![]() |
63689deb45 | ||
![]() |
921752d3e2 | ||
![]() |
3d126ec89f | ||
![]() |
07d60e8f19 | ||
![]() |
a9f810b203 | ||
![]() |
f3c4fec43f | ||
![]() |
652c3e76c7 | ||
![]() |
bc814cfb2c | ||
![]() |
d4f2b9050d | ||
![]() |
70d7979439 | ||
![]() |
019b2050e1 | ||
![]() |
8d68dbf906 | ||
![]() |
2ea14c0cf4 | ||
![]() |
1dbede5b93 | ||
![]() |
803649da11 | ||
![]() |
82f08f33c1 | ||
![]() |
d3e495ce03 | ||
![]() |
8c81ed8678 | ||
![]() |
65170e8dad | ||
![]() |
28e31f5d3d | ||
![]() |
ab72799841 | ||
![]() |
986b92eb07 | ||
![]() |
7ba0f623d7 | ||
![]() |
de7306a250 | ||
![]() |
7ba043f0f3 | ||
![]() |
98ec3fdf74 | ||
![]() |
e3c3f4730d | ||
![]() |
8051092414 | ||
![]() |
9fafdcb99c | ||
![]() |
7da1639a14 | ||
![]() |
1437144740 | ||
![]() |
d55330bcd1 | ||
![]() |
351613bc1f | ||
![]() |
4b02d1f6f6 | ||
![]() |
d3cded796c | ||
![]() |
c7d8812ca7 | ||
![]() |
e4516a90b1 | ||
![]() |
255bf6e5b1 | ||
![]() |
1b0dedb81c | ||
![]() |
df96276b19 | ||
![]() |
ed5e70465a | ||
![]() |
7380f8ec71 | ||
![]() |
dca8b3fede | ||
![]() |
c67398d31b | ||
![]() |
9397fdafe1 | ||
![]() |
44f1dbee0d | ||
![]() |
0251a25541 | ||
![]() |
ccdb37b075 | ||
![]() |
34791f7988 | ||
![]() |
9045656014 | ||
![]() |
67d6f2baa4 | ||
![]() |
5662bdafc2 | ||
![]() |
3ee144aa95 | ||
![]() |
234be4aebc | ||
![]() |
1e2f86394a | ||
![]() |
700840f4b7 | ||
![]() |
e2fa151f9c | ||
![]() |
8e5ef60540 | ||
![]() |
118759aa6b | ||
![]() |
fe7cd80cbc | ||
![]() |
e2e6c159d3 | ||
![]() |
0eb708aa8a | ||
![]() |
bd0555ecd4 | ||
![]() |
827cfe4a76 | ||
![]() |
b4c759716a | ||
![]() |
6926fc1615 | ||
![]() |
2fcdeb0128 | ||
![]() |
d7e0d46ffa | ||
![]() |
34b4df774d | ||
![]() |
5aa35691ab | ||
![]() |
95a255a548 | ||
![]() |
f9f6dc4262 | ||
![]() |
e3e8dfe99c | ||
![]() |
95e29dab70 | ||
![]() |
afca5b564e | ||
![]() |
54d6055098 | ||
![]() |
6e5671b00d | ||
![]() |
1c723b2e6f | ||
![]() |
b64c2d763e | ||
![]() |
284b0e4fa2 | ||
![]() |
223ac7782e | ||
![]() |
fd973c0a4e | ||
![]() |
7432781e71 | ||
![]() |
07d06dd396 | ||
![]() |
1de276bbcd | ||
![]() |
b0f97177d4 | ||
![]() |
d2d1b5e944 | ||
![]() |
5333d6371b | ||
![]() |
07b33c3266 | ||
![]() |
f29856d034 | ||
![]() |
c58c650adf | ||
![]() |
9272dc9597 | ||
![]() |
3341ab0776 | ||
![]() |
aa47c8efa9 | ||
![]() |
287955cfb4 | ||
![]() |
2d6120240d | ||
![]() |
51caf0a3af | ||
![]() |
fd76646a95 | ||
![]() |
ec9931fae1 | ||
![]() |
0f4623d346 | ||
![]() |
52be3b14e3 | ||
![]() |
2f8fb4f28a | ||
![]() |
0977f70f4d | ||
![]() |
ee3f9a1e03 | ||
![]() |
0814086a23 | ||
![]() |
60af1a1db2 | ||
![]() |
b8763cb215 | ||
![]() |
a8dd5c7e41 | ||
![]() |
74ca73d545 | ||
![]() |
d77d961b35 | ||
![]() |
c8fbb0d2ee | ||
![]() |
4a706a7092 | ||
![]() |
064ff74cdb | ||
![]() |
5111d66ac9 | ||
![]() |
092962b07c | ||
![]() |
6a728382f9 | ||
![]() |
3aa833e0d9 | ||
![]() |
7c15987444 | ||
![]() |
dc00b37965 | ||
![]() |
0ee5a4d481 | ||
![]() |
627d0a2b32 | ||
![]() |
51a967d58a | ||
![]() |
f908fe4462 | ||
![]() |
f068386c9f | ||
![]() |
5a94edad70 | ||
![]() |
ff2cbe8fac | ||
![]() |
c73a827564 | ||
![]() |
3647b821ea | ||
![]() |
5b1561bb71 | ||
![]() |
c0f46daca5 | ||
![]() |
454abde1aa | ||
![]() |
00eff4b196 | ||
![]() |
36d143e707 | ||
![]() |
8af9f8ab5e | ||
![]() |
1ffc7d6bf8 | ||
![]() |
2c960e8f04 | ||
![]() |
ca16b54c86 | ||
![]() |
cf59631f65 | ||
![]() |
666a82374d | ||
![]() |
12720e929d | ||
![]() |
bd37348939 | ||
![]() |
3ebde5ea14 | ||
![]() |
1e9e523521 | ||
![]() |
5e192dbce2 | ||
![]() |
1867f2a830 | ||
![]() |
2d11b981bf | ||
![]() |
fece489794 | ||
![]() |
28e8190185 | ||
![]() |
f9dec1228d | ||
![]() |
57d99a515f | ||
![]() |
e8785c2e94 | ||
![]() |
1e1384b6dd | ||
![]() |
a8edf6e445 | ||
![]() |
379c37fa0b | ||
![]() |
98f5aa2564 | ||
![]() |
b10cb0296a | ||
![]() |
4983fa45fc | ||
![]() |
b788c7fa6c | ||
![]() |
74edfebbde | ||
![]() |
b01921cb55 | ||
![]() |
d9405c7935 | ||
![]() |
4ef9dcb1eb | ||
![]() |
71e133e5e6 | ||
![]() |
eae2d3b145 | ||
![]() |
974a3aa2c4 | ||
![]() |
9722bd7b1b | ||
![]() |
5cdfa3324f | ||
![]() |
8cf413e450 | ||
![]() |
18caa5fb23 | ||
![]() |
8e2a9cbaa3 | ||
![]() |
d9149a9a09 | ||
![]() |
0b61bc8982 | ||
![]() |
3af43cffa0 | ||
![]() |
e5ddf7ae7d | ||
![]() |
9b239a6a86 | ||
![]() |
ec18ebcb41 | ||
![]() |
0e7479bb76 | ||
![]() |
ec6670080a | ||
![]() |
4a36f234ac | ||
![]() |
2322ae403b | ||
![]() |
7e8b7bba21 | ||
![]() |
32325a66ca | ||
![]() |
8a40213eb3 | ||
![]() |
e76a7e8afb | ||
![]() |
f517fcd148 | ||
![]() |
42657e70b8 | ||
![]() |
2ee896201c | ||
![]() |
04901f4ee7 | ||
![]() |
089c28b1e8 | ||
![]() |
216cc893bf | ||
![]() |
57b4fb5c53 | ||
![]() |
4dabeff308 | ||
![]() |
2e5958186a | ||
![]() |
28eaec5e15 | ||
![]() |
ee143aaf65 | ||
![]() |
8a7c9c971f | ||
![]() |
b41e066aa1 | ||
![]() |
cb247e06f0 | ||
![]() |
90d15227c5 | ||
![]() |
de96063bda | ||
![]() |
49756ebc70 | ||
![]() |
87b4469adc | ||
![]() |
76cbe9c8f8 | ||
![]() |
e87d2ae383 | ||
![]() |
e4f37481ff | ||
![]() |
431c037709 | ||
![]() |
75fe540500 | ||
![]() |
99529577cc | ||
![]() |
5f9f5bc04d | ||
![]() |
b4906577c9 | ||
![]() |
f4fc769c81 | ||
![]() |
6e12ef4a7b | ||
![]() |
295ab46ea0 | ||
![]() |
d6a5bc4e8b | ||
![]() |
ab00aec67b | ||
![]() |
0d73ec5834 | ||
![]() |
52b19e0124 | ||
![]() |
686e7aca40 | ||
![]() |
675ee057e0 | ||
![]() |
62da4e2949 | ||
![]() |
89bc945554 | ||
![]() |
78d2e0b43e | ||
![]() |
874e214993 | ||
![]() |
6ef5dd5266 | ||
![]() |
2681e1fce3 | ||
![]() |
cb31663663 | ||
![]() |
f4ee0ab2f1 | ||
![]() |
5554fcc286 | ||
![]() |
95ab723995 | ||
![]() |
ade58885c4 | ||
![]() |
75cbd9a8ae | ||
![]() |
18fa61049a | ||
![]() |
edb9d0d21e | ||
![]() |
e2e0f92f17 | ||
![]() |
2331c52aff | ||
![]() |
ae98d0a560 | ||
![]() |
59e02ee93b | ||
![]() |
d96a685fae | ||
![]() |
558de3d9ad | ||
![]() |
07f048a8d7 | ||
![]() |
e1f1386d5e | ||
![]() |
e4172bcbdf | ||
![]() |
b20fc95c1a | ||
![]() |
d01d476480 | ||
![]() |
703f4037c4 | ||
![]() |
ce0c0c31a0 | ||
![]() |
424d30fe97 | ||
![]() |
c5044bd021 | ||
![]() |
750e1836af | ||
![]() |
8f40ffdb92 | ||
![]() |
797195e0ea | ||
![]() |
f9280cde0a | ||
![]() |
162edf7b30 | ||
![]() |
ce590e2077 | ||
![]() |
0af780e8df | ||
![]() |
e39cdafed9 | ||
![]() |
5975ddbdb8 | ||
![]() |
28f6199474 | ||
![]() |
cd95ea5d48 | ||
![]() |
10fde593f1 | ||
![]() |
17db70f3af | ||
![]() |
90d59e6c8a | ||
![]() |
3029357520 | ||
![]() |
c17caca9b7 | ||
![]() |
44f70b4be1 | ||
![]() |
fbac254511 | ||
![]() |
bf62672d59 | ||
![]() |
767a52ba30 | ||
![]() |
f4ddbaeb9e | ||
![]() |
d9f4c1db23 | ||
![]() |
9757b11aaf | ||
![]() |
a9aedfbc58 | ||
![]() |
d5a6040967 | ||
![]() |
9acb52c8f3 | ||
![]() |
c5f3b4ca02 | ||
![]() |
c46b7ab9a3 | ||
![]() |
2e68e9c051 | ||
![]() |
0926098e9d |
@@ -18,6 +18,7 @@ Checks: >
|
||||
-bugprone-not-null-terminated-result,
|
||||
-bugprone-suspicious-memory-comparison,
|
||||
-bugprone-switch-missing-default-case,
|
||||
-bugprone-tagged-union-member-count,
|
||||
-cert-env33-c,
|
||||
-cert-err33-c,
|
||||
-cert-err34-c,
|
||||
@@ -63,6 +64,7 @@ Checks: >
|
||||
|
||||
Aliases. These are just duplicates of other warnings and should always be ignored,
|
||||
-bugprone-narrowing-conversions,
|
||||
-cert-arr39-c,
|
||||
-cert-dcl37-c,
|
||||
-cert-dcl51-cpp,
|
||||
-cert-exp42-c,
|
||||
|
25
.emmyrc.json
Normal file
25
.emmyrc.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
|
||||
"format": {
|
||||
"externalTool": {
|
||||
"program": "stylua",
|
||||
"args": [
|
||||
"-",
|
||||
"--stdin-filepath",
|
||||
"${file}"
|
||||
]
|
||||
}
|
||||
},
|
||||
"diagnostics": {
|
||||
"disable": [
|
||||
"unnecessary-if"
|
||||
]
|
||||
},
|
||||
"codeAction": {
|
||||
"insertSpace": true
|
||||
},
|
||||
"strict": {
|
||||
"typeCall": true,
|
||||
"arrayIndex": true
|
||||
}
|
||||
}
|
0
.gitattributes
vendored
Executable file → Normal file
0
.gitattributes
vendored
Executable file → Normal file
5
.github/pull_request_template.md
vendored
Normal file
5
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<!--
|
||||
Thank you for contributing to Neovim!
|
||||
If this is your first time, check out https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#pull-requests-prs
|
||||
for our PR guidelines.
|
||||
-->
|
2
.github/scripts/reviewers_add.js
vendored
2
.github/scripts/reviewers_add.js
vendored
@@ -57,6 +57,7 @@ module.exports = async ({ github, context }) => {
|
||||
|
||||
if (labels.includes("lsp")) {
|
||||
reviewers.add("MariaSolOs");
|
||||
reviewers.add("ribru17");
|
||||
}
|
||||
|
||||
if (labels.includes("netrw")) {
|
||||
@@ -89,6 +90,7 @@ module.exports = async ({ github, context }) => {
|
||||
reviewers.add("clason");
|
||||
reviewers.add("lewis6991");
|
||||
reviewers.add("wookayin");
|
||||
reviewers.add("ribru17");
|
||||
}
|
||||
|
||||
if (labels.includes("tui")) {
|
||||
|
4
.github/workflows/backport.yml
vendored
4
.github/workflows/backport.yml
vendored
@@ -11,9 +11,9 @@ jobs:
|
||||
if: github.event.pull_request.merged
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: actions/create-github-app-token@v1
|
||||
- uses: actions/create-github-app-token@v2
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.BACKPORT_APP }}
|
||||
|
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
test: [ubuntu-latest, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.test }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
- run: |
|
||||
cmake -S cmake.deps --preset ci -D ENABLE_WASMTIME=ON
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
CMAKE_URL: 'https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.sh'
|
||||
CMAKE_VERSION: '3.16.0'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Install minimum required version of cmake
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
name: Test USE_EXISTING_SRC_DIR=ON builds with no network access
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Build bundled dependencies
|
||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Initialize CodeQL
|
||||
|
2
.github/workflows/coverity.yml
vendored
2
.github/workflows/coverity.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Download Coverity
|
||||
|
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Generate docs
|
||||
|
2
.github/workflows/labeler_pr.yml
vendored
2
.github/workflows/labeler_pr.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
configuration-path: .github/scripts/labeler_configuration.yml
|
||||
|
2
.github/workflows/lintcommit.yml
vendored
2
.github/workflows/lintcommit.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.draft == false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
2
.github/workflows/news.yml
vendored
2
.github/workflows/news.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci:skip-news')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
6
.github/workflows/notes.md
vendored
6
.github/workflows/notes.md
vendored
@@ -36,7 +36,7 @@ Note: On Windows "Server" you may need to [install vcruntime140.dll](https://lea
|
||||
|
||||
### Linux (x86_64)
|
||||
|
||||
If your system does not have the [required glibc version](https://neovim.io/doc/user/support.html#supported-platforms), try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases).
|
||||
If your system does not have the required glibc version, try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases).
|
||||
|
||||
#### AppImage
|
||||
|
||||
@@ -54,7 +54,7 @@ If your system does not have the [required glibc version](https://neovim.io/doc/
|
||||
2. Extract: `tar xzvf nvim-linux-x86_64.tar.gz`
|
||||
3. Run `./nvim-linux-x86_64/bin/nvim`
|
||||
|
||||
### Linux (arm64) - Untested
|
||||
### Linux (arm64)
|
||||
|
||||
#### AppImage
|
||||
|
||||
@@ -75,5 +75,3 @@ If your system does not have the [required glibc version](https://neovim.io/doc/
|
||||
### Other
|
||||
|
||||
- Install by [package manager](https://github.com/neovim/neovim/blob/master/INSTALL.md#install-from-package)
|
||||
|
||||
## SHA256 Checksums
|
||||
|
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
outputs:
|
||||
version: ${{ steps.build.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# Perform a full checkout #13471
|
||||
fetch-depth: 0
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# Perform a full checkout #13471
|
||||
fetch-depth: 0
|
||||
@@ -132,9 +132,9 @@ jobs:
|
||||
|
||||
windows:
|
||||
needs: setup
|
||||
runs-on: windows-2019
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# Perform a full checkout #13471
|
||||
fetch-depth: 0
|
||||
@@ -166,9 +166,9 @@ jobs:
|
||||
steps:
|
||||
# Must perform checkout first, since it deletes the target directory
|
||||
# before running, and would therefore delete the downloaded artifacts
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y gettext-base
|
||||
@@ -193,25 +193,13 @@ jobs:
|
||||
echo 'PRERELEASE=') >> $GITHUB_ENV
|
||||
gh release delete stable --yes || true
|
||||
git push origin :stable || true
|
||||
# `sha256sum` outputs <sha> <path>, so we cd into each dir to drop the
|
||||
# containing folder from the output.
|
||||
- run: |
|
||||
for i in nvim-*; do
|
||||
(
|
||||
cd $i || exit
|
||||
sha256sum * >> $GITHUB_WORKSPACE/shasum.txt
|
||||
)
|
||||
done
|
||||
- name: Publish release
|
||||
env:
|
||||
NVIM_VERSION: ${{ needs.linux.outputs.version }}
|
||||
DEBUG: api
|
||||
run: |
|
||||
envsubst < "$GITHUB_WORKSPACE/.github/workflows/notes.md" > "$RUNNER_TEMP/notes.md"
|
||||
echo '```' >> "$RUNNER_TEMP/notes.md"
|
||||
cat shasum.txt >> "$RUNNER_TEMP/notes.md"
|
||||
echo '```' >> "$RUNNER_TEMP/notes.md"
|
||||
if [ "$TAG_NAME" != "nightly" ]; then
|
||||
gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win64/* shasum.txt
|
||||
gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win64/*
|
||||
fi
|
||||
gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win64/* shasum.txt
|
||||
gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win64/*
|
||||
|
4
.github/workflows/response.yml
vendored
4
.github/workflows/response.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
|
2
.github/workflows/reviewers_add.yml
vendored
2
.github/workflows/reviewers_add.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: 'Request reviewers'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
|
2
.github/workflows/reviewers_remove.yml
vendored
2
.github/workflows/reviewers_remove.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: 'Remove reviewers'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
|
42
.github/workflows/test.yml
vendored
42
.github/workflows/test.yml
vendored
@@ -28,17 +28,17 @@ env:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CC: clang
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Install stylua
|
||||
run: |
|
||||
wget --directory-prefix="$BIN_DIR" https://github.com/JohnnyMorganz/StyLua/releases/latest/download/stylua-linux-x86_64.zip
|
||||
wget --directory-prefix="$BIN_DIR" https://github.com/JohnnyMorganz/StyLua/releases/latest/download/stylua-linux-aarch64.zip
|
||||
(cd "$BIN_DIR"; unzip stylua*.zip)
|
||||
|
||||
- name: Build third-party deps
|
||||
@@ -82,12 +82,12 @@ jobs:
|
||||
run: cmake --build build --target lintc-uncrustify
|
||||
|
||||
clang-analyzer:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
CC: clang
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
- name: Build third-party deps
|
||||
run: |
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: tsan, cc: clang, flags: -D ENABLE_TSAN=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: release, cc: gcc, flags: -D CMAKE_BUILD_TYPE=Release -D ENABLE_TRANSLATIONS=ON },
|
||||
# { runner: ubuntu-24.04-arm, os: ubuntu, flavor: arm, cc: gcc, flags: -D CMAKE_BUILD_TYPE=RelWithDebInfo },
|
||||
{ runner: ubuntu-24.04-arm, os: ubuntu, flavor: arm, cc: clang, flags: -D CMAKE_BUILD_TYPE=RelWithDebInfo },
|
||||
{ runner: macos-13, os: macos, flavor: intel, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: macos-15, os: macos, flavor: arm, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON },
|
||||
@@ -124,12 +124,17 @@ jobs:
|
||||
build: { flavor: puc-lua }
|
||||
- test: oldtest
|
||||
build: { flavor: tsan }
|
||||
- test: unittest
|
||||
build: { runner: ubuntu-24.04-arm }
|
||||
- test: oldtest
|
||||
build: { runner: ubuntu-24.04-arm }
|
||||
runs-on: ${{ matrix.build.runner }}
|
||||
timeout-minutes: 45
|
||||
env:
|
||||
CC: ${{ matrix.build.cc }}
|
||||
NVIM_TEST_INTEG: ${{ matrix.build.flavor == 'release' && '1' || '0' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
with:
|
||||
install_flags: "--test"
|
||||
@@ -201,16 +206,35 @@ jobs:
|
||||
name: Show logs
|
||||
run: cat $(find "$LOG_DIR" -type f)
|
||||
|
||||
zig-build:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 45
|
||||
name: build using zig build (linux)
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.14.1
|
||||
- run: sudo apt-get install -y inotify-tools
|
||||
- run: zig build test_nlua0
|
||||
- run: zig build nvim && ./zig-out/bin/nvim --version
|
||||
- run: zig build unittest
|
||||
- run: zig build functionaltest
|
||||
# `zig build nvim` uses a lua script for doctags in order to support cross-compiling
|
||||
# compare with the builtin generator that they match
|
||||
- run: cd runtime; ../zig-out/bin/nvim -u NONE -i NONE -e --headless -c "helptags ++t doc" -c quit
|
||||
- run: diff -u runtime/doc/tags zig-out/runtime/doc/tags
|
||||
|
||||
windows:
|
||||
uses: ./.github/workflows/test_windows.yml
|
||||
|
||||
with-external-deps:
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CC: gcc
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Install dependencies
|
||||
|
2
.github/workflows/test_windows.yml
vendored
2
.github/workflows/test_windows.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
matrix:
|
||||
test: [functional, old]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Build deps
|
||||
|
4
.github/workflows/vim_patches.yml
vendored
4
.github/workflows/vim_patches.yml
vendored
@@ -15,11 +15,11 @@ jobs:
|
||||
VERSION_BRANCH: marvim/ci-version-update
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
repository: vim/vim
|
||||
path: ${{ env.VIM_SOURCE_DIR }}
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,7 +10,8 @@ compile_commands.json
|
||||
/.idea/
|
||||
|
||||
# Build/deps dir
|
||||
/build/
|
||||
/.zig-cache/
|
||||
/zig-out/
|
||||
/.deps/
|
||||
/tmp/
|
||||
/.clangd/
|
||||
|
@@ -49,6 +49,7 @@ exclude_files = {
|
||||
'runtime/lua/vim/_meta/vimfn.lua',
|
||||
'runtime/lua/vim/_meta/api.lua',
|
||||
'runtime/lua/vim/re.lua',
|
||||
'runtime/lua/uv/_meta.lua',
|
||||
'runtime/lua/coxpcall.lua',
|
||||
'src/nvim/eval.lua',
|
||||
}
|
||||
|
@@ -5,13 +5,12 @@
|
||||
},
|
||||
"workspace": {
|
||||
"library": [
|
||||
"runtime/lua",
|
||||
"${3rd}/busted/library",
|
||||
"${3rd}/luv/library"
|
||||
"${3rd}/busted/library"
|
||||
],
|
||||
"ignoreDir": [
|
||||
"test",
|
||||
"_vim9script.lua"
|
||||
".deps",
|
||||
"build",
|
||||
"test"
|
||||
],
|
||||
"checkThirdParty": "Disable"
|
||||
},
|
||||
|
8
.stylua2.toml
Normal file
8
.stylua2.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
# Alternative settings for special snowflakes like: decorations_spec.lua, multigrid_spec.lua, etc.
|
||||
|
||||
column_width = 140
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferSingle"
|
||||
call_parentheses = "Input"
|
@@ -1,14 +1,15 @@
|
||||
/build/
|
||||
/.deps/
|
||||
/runtime/lua/coxpcall.lua
|
||||
/runtime/lua/vim/_meta
|
||||
/runtime/lua/vim/re.lua
|
||||
build/
|
||||
.deps/
|
||||
runtime/lua/coxpcall.lua
|
||||
runtime/lua/uv/_meta.lua
|
||||
runtime/lua/vim/_meta
|
||||
runtime/lua/vim/re.lua
|
||||
|
||||
# These are formatted explicitly by the "formatlua2" build task.
|
||||
test/functional/ui/decorations_spec.lua
|
||||
test/functional/ui/float_spec.lua
|
||||
test/functional/ui/multigrid_spec.lua
|
||||
/test/functional/fixtures/lua/syntax_error.lua
|
||||
/test/functional/legacy/030_fileformats_spec.lua
|
||||
/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
|
||||
/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
|
||||
/test/functional/lua/luaeval_spec.lua
|
||||
test/functional/fixtures/lua/syntax_error.lua
|
||||
test/functional/legacy/030_fileformats_spec.lua
|
||||
test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
|
||||
test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
|
||||
|
74
BUILD.md
74
BUILD.md
@@ -165,11 +165,40 @@ https://github.com/cascent/neovim-cygwin was built on Cygwin 2.9.0. Newer `libuv
|
||||
mingw32-make install
|
||||
```
|
||||
|
||||
### Windows WSL
|
||||
|
||||
Build Ubuntu/Debian linux binary on [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) (Windows Subsystem for Linux).
|
||||
|
||||
```bash
|
||||
# Install build prerequisites
|
||||
sudo apt-get install ninja-build gettext cmake build-essential
|
||||
|
||||
# Build the linux binary in WSL
|
||||
make CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
# Install the linux binary in WSL (with `<arch>` either `x86_64` or `arm64`)
|
||||
cd build && cpack -G DEB && sudo dpkg -i nvim-linux-<arch>.deb
|
||||
|
||||
# Verify the installation
|
||||
nvim --version && which nvim # should be debug build in /usr/bin/nvim
|
||||
```
|
||||
|
||||
**Note**: If you encounter linker errors or segfaults during the build, Windows libraries in your PATH may be interfering. Use a clean PATH to avoid conflicts:
|
||||
|
||||
```bash
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" make CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
```
|
||||
|
||||
## Localization
|
||||
|
||||
### Localization build
|
||||
|
||||
A normal build will create `.mo` files in `build/src/nvim/po`.
|
||||
Translations are turned off by default. Enable by building Nvim with the CMake flag `ENABLE_TRANSLATIONS=ON`.
|
||||
Doing this will create `.mo` files in `build/src/nvim/po`. Example:
|
||||
|
||||
```
|
||||
make CMAKE_EXTRA_FLAGS="-DENABLE_TRANSLATIONS=ON"
|
||||
```
|
||||
|
||||
* If you see `msgfmt: command not found`, you need to install [`gettext`](http://en.wikipedia.org/wiki/Gettext). On most systems, the package is just called `gettext`.
|
||||
|
||||
@@ -223,7 +252,7 @@ rebuild:
|
||||
|
||||
## Third-party dependencies
|
||||
|
||||
Reference the [Debian package](https://packages.debian.org/sid/source/neovim) (or alternatively, the [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/neovim.rb)) for the precise list of dependencies/versions.
|
||||
Reference the [Debian package](https://packages.debian.org/sid/source/neovim) (or alternatively, the [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/n/neovim.rb)) for the precise list of dependencies/versions.
|
||||
|
||||
To build the bundled dependencies using CMake:
|
||||
|
||||
@@ -259,6 +288,29 @@ cmake --build build
|
||||
- Using `ninja` is strongly recommended.
|
||||
4. If treesitter parsers are not bundled, they need to be available in a `parser/` runtime directory (e.g. `/usr/share/nvim/runtime/parser/`).
|
||||
|
||||
### How to build static binary (on Linux)
|
||||
|
||||
1. Use a linux distribution which uses musl C. We will use Alpine Linux but any distro with musl should work. (glibc does not support static linking)
|
||||
2. Run make passing the `STATIC_BUILD` variable: `make CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"`
|
||||
|
||||
In case you are not using Alpine Linux you can use a container to do the build the binary:
|
||||
|
||||
```bash
|
||||
podman run \
|
||||
--rm \
|
||||
-it \
|
||||
-v "$PWD:/workdir" \
|
||||
-w /workdir \
|
||||
alpine:latest \
|
||||
bash -c 'apk add build-base cmake coreutils curl gettext-tiny-dev git && make CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"'
|
||||
```
|
||||
|
||||
The resulting binary in `build/bin/nvim` will have all the dependencies statically linked:
|
||||
|
||||
```
|
||||
build/bin/nvim: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=b93fa8e678d508ac0a76a2e3da20b119105f1b2d, with debug_info, not stripped
|
||||
```
|
||||
|
||||
#### Debian 10 (Buster) example:
|
||||
|
||||
```sh
|
||||
@@ -294,31 +346,31 @@ Platform-specific requirements are listed below.
|
||||
### Ubuntu / Debian
|
||||
|
||||
```sh
|
||||
sudo apt-get install ninja-build gettext cmake curl build-essential
|
||||
sudo apt-get install ninja-build gettext cmake curl build-essential git
|
||||
```
|
||||
|
||||
### RHEL / Fedora
|
||||
|
||||
```
|
||||
sudo dnf -y install ninja-build cmake gcc make gettext curl glibc-gconv-extra
|
||||
sudo dnf -y install ninja-build cmake gcc make gettext curl glibc-gconv-extra git
|
||||
```
|
||||
|
||||
### openSUSE
|
||||
|
||||
```
|
||||
sudo zypper install ninja cmake gcc-c++ gettext-tools curl
|
||||
sudo zypper install ninja cmake gcc-c++ gettext-tools curl git
|
||||
```
|
||||
|
||||
### Arch Linux
|
||||
|
||||
```
|
||||
sudo pacman -S base-devel cmake ninja curl
|
||||
sudo pacman -S base-devel cmake ninja curl git
|
||||
```
|
||||
|
||||
### Alpine Linux
|
||||
|
||||
```
|
||||
apk add build-base cmake coreutils curl gettext-tiny-dev
|
||||
apk add build-base cmake coreutils curl gettext-tiny-dev git
|
||||
```
|
||||
|
||||
### Void Linux
|
||||
@@ -382,7 +434,7 @@ or a specific SHA1 like `--override-input neovim-src github:neovim/neovim/89dc8f
|
||||
### FreeBSD
|
||||
|
||||
```
|
||||
sudo pkg install cmake gmake sha wget gettext curl
|
||||
sudo pkg install cmake gmake sha wget gettext curl git
|
||||
```
|
||||
|
||||
If you get an error regarding a `sha256sum` mismatch, where the actual SHA-256 hash is `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, then this is your issue (that's the `sha256sum` of an empty file).
|
||||
@@ -390,7 +442,7 @@ If you get an error regarding a `sha256sum` mismatch, where the actual SHA-256 h
|
||||
### OpenBSD
|
||||
|
||||
```sh
|
||||
doas pkg_add gmake cmake curl gettext-tools
|
||||
doas pkg_add gmake cmake curl gettext-tools git
|
||||
```
|
||||
|
||||
Build can sometimes fail when using the top level `Makefile`, apparently due to some third-party component (see [#2445-comment](https://github.com/neovim/neovim/issues/2445#issuecomment-108124236)). The following instructions use CMake:
|
||||
@@ -415,7 +467,7 @@ gmake
|
||||
2. Install [Homebrew](http://brew.sh)
|
||||
3. Install Neovim build dependencies:
|
||||
```
|
||||
brew install ninja cmake gettext curl
|
||||
brew install ninja cmake gettext curl git
|
||||
```
|
||||
- **Note**: If you see Wget certificate errors (for older macOS versions less than 10.10):
|
||||
```sh
|
||||
@@ -433,7 +485,7 @@ gmake
|
||||
2. Install [MacPorts](http://www.macports.org)
|
||||
3. Install Neovim build dependencies:
|
||||
```
|
||||
sudo port install ninja cmake gettext
|
||||
sudo port install ninja cmake gettext git
|
||||
```
|
||||
- **Note**: If you see Wget certificate errors (for older macOS versions less than 10.10):
|
||||
```sh
|
||||
|
@@ -35,6 +35,11 @@ include(InstallHelpers)
|
||||
include(PreventInTreeBuilds)
|
||||
include(Util)
|
||||
|
||||
if(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
||||
# Auto-create a .gitignore in the specified "build" directory.
|
||||
file(GENERATE OUTPUT .gitignore CONTENT "*")
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# User settings
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -140,19 +145,19 @@ endif()
|
||||
# If not in a git repo (e.g., a tarball) these tokens define the complete
|
||||
# version string, else they are combined with the result of `git describe`.
|
||||
set(NVIM_VERSION_MAJOR 0)
|
||||
set(NVIM_VERSION_MINOR 11)
|
||||
set(NVIM_VERSION_MINOR 12)
|
||||
set(NVIM_VERSION_PATCH 0)
|
||||
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
|
||||
set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers
|
||||
|
||||
# API level
|
||||
set(NVIM_API_LEVEL 13) # Bump this after any API/stdlib change.
|
||||
set(NVIM_API_LEVEL 14) # Bump this after any API/stdlib change.
|
||||
set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change.
|
||||
set(NVIM_API_PRERELEASE false)
|
||||
set(NVIM_API_PRERELEASE true)
|
||||
|
||||
# We _want_ assertions in RelWithDebInfo build-type.
|
||||
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG)
|
||||
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REPLACE "-DNDEBUG" "-DRELDEBUG" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REPLACE "/DNDEBUG" "/DRELDEBUG" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
string(REPLACE " " " " CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") # Remove duplicate whitespace
|
||||
endif()
|
||||
|
||||
@@ -236,7 +241,7 @@ set(STYLUA_DIRS runtime scripts src test contrib)
|
||||
add_glob_target(
|
||||
TARGET lintlua-luacheck
|
||||
COMMAND $<TARGET_FILE:nvim_bin>
|
||||
FLAGS -ll ${PROJECT_SOURCE_DIR}/test/lua_runner.lua ${CMAKE_BINARY_DIR}/usr luacheck -q
|
||||
FLAGS -ll ${PROJECT_SOURCE_DIR}/test/lua_runner.lua ${CMAKE_BINARY_DIR}/usr/share/lua/5.1 luacheck -q
|
||||
GLOB_DIRS runtime scripts src test
|
||||
GLOB_PAT *.lua
|
||||
TOUCH_STRATEGY PER_DIR)
|
||||
@@ -249,6 +254,16 @@ add_glob_target(
|
||||
GLOB_DIRS ${STYLUA_DIRS}
|
||||
GLOB_PAT *.lua
|
||||
TOUCH_STRATEGY PER_DIR)
|
||||
# Special handling of some files (which are ignored in .styluaignore).
|
||||
# Workaround because stylua doesn't(?) support file-specific settings.
|
||||
add_custom_target(lintlua-stylua2
|
||||
COMMAND ${STYLUA_PRG} --config-path "${PROJECT_SOURCE_DIR}/.stylua2.toml"
|
||||
--color=always --check
|
||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/decorations_spec.lua"
|
||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/float_spec.lua"
|
||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/multigrid_spec.lua"
|
||||
)
|
||||
add_dependencies(lintlua-stylua lintlua-stylua2)
|
||||
|
||||
add_custom_target(lintlua)
|
||||
add_dependencies(lintlua lintlua-luacheck lintlua-stylua)
|
||||
@@ -262,7 +277,7 @@ add_glob_target(
|
||||
TOUCH_STRATEGY PER_DIR)
|
||||
|
||||
add_custom_target(lintcommit
|
||||
COMMAND $<TARGET_FILE:nvim_bin> -u NONE -l ${PROJECT_SOURCE_DIR}/scripts/lintcommit.lua main)
|
||||
COMMAND $<TARGET_FILE:nvim_bin> --clean -l ${PROJECT_SOURCE_DIR}/scripts/lintcommit.lua main)
|
||||
add_dependencies(lintcommit nvim_bin)
|
||||
|
||||
add_custom_target(lint)
|
||||
@@ -276,7 +291,15 @@ add_glob_target(
|
||||
GLOB_DIRS ${STYLUA_DIRS}
|
||||
GLOB_PAT *.lua
|
||||
TOUCH_STRATEGY PER_DIR)
|
||||
|
||||
# Special handling of some files (which are ignored in .styluaignore).
|
||||
# Workaround because stylua doesn't(?) support file-specific settings.
|
||||
add_custom_target(formatlua2
|
||||
COMMAND ${STYLUA_PRG} --config-path "${PROJECT_SOURCE_DIR}/.stylua2.toml"
|
||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/decorations_spec.lua"
|
||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/float_spec.lua"
|
||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/multigrid_spec.lua"
|
||||
)
|
||||
add_dependencies(formatlua formatlua2)
|
||||
add_custom_target(format)
|
||||
add_dependencies(format formatc formatlua)
|
||||
|
||||
@@ -323,13 +346,13 @@ else()
|
||||
add_custom_target(lua_dev_deps)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES arm64)
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm|aarch")
|
||||
set(LUALS_ARCH arm64)
|
||||
else()
|
||||
set(LUALS_ARCH x64)
|
||||
endif()
|
||||
|
||||
set(LUALS_VERSION 3.13.9)
|
||||
set(LUALS_VERSION 3.15.0)
|
||||
set(LUALS "lua-language-server-${LUALS_VERSION}-${CMAKE_SYSTEM_NAME}-${LUALS_ARCH}")
|
||||
set(LUALS_TARBALL ${LUALS}.tar.gz)
|
||||
set(LUALS_URL https://github.com/LuaLS/lua-language-server/releases/download/${LUALS_VERSION}/${LUALS_TARBALL})
|
||||
|
@@ -273,7 +273,7 @@ If you need to modify or debug the documentation flow, these are the main files:
|
||||
runtime/lua/vim/* => runtime/doc/lua.txt
|
||||
runtime/lua/vim/lsp/ => runtime/doc/lsp.txt
|
||||
src/nvim/api/* => runtime/doc/api.txt
|
||||
src/nvim/eval.lua => runtime/doc/builtin.txt
|
||||
src/nvim/eval.lua => runtime/doc/vimfn.txt
|
||||
src/nvim/options.lua => runtime/doc/options.txt
|
||||
```
|
||||
|
||||
@@ -299,7 +299,7 @@ types, etc. See [:help dev-lua-doc][dev-lua-doc].
|
||||
- If possible, add type information (`table`, `string`, `number`, ...). Multiple valid types are separated by a bar (`string|table`). Indicate optional parameters via `type|nil`.
|
||||
- If a function in your Lua module should _not_ be documented, add `@nodoc`.
|
||||
- If the function is internal or otherwise non-public add `@private`.
|
||||
- Private functions usually should be underscore-prefixed (named "_foo", not "foo").
|
||||
- Private functions usually should be underscore-prefixed (named "_foo", not "foo"). Prefixing with an underscore implies `@nodoc`.
|
||||
- Mark deprecated functions with `@deprecated`.
|
||||
|
||||
Third-party dependencies
|
||||
|
12
INSTALL.md
12
INSTALL.md
@@ -62,15 +62,17 @@ Several Neovim GUIs are available from scoop (extras): [scoop.sh/#/apps?q=neovim
|
||||
|
||||
- Add the `bin` folder (e.g. `C:\Program Files\nvim\bin`) to your PATH.
|
||||
- This makes it easy to run `nvim` from anywhere.
|
||||
- If `:set spell` does not work, create the `C:/Users/foo/AppData/Local/nvim/site/spell` folder.
|
||||
- If `:set spell` does not work, create the `%LOCALAPPDATA%/nvim-data/site/spell` folder.
|
||||
You can then copy your spell files over (for English, located
|
||||
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.spl) and
|
||||
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.sug));
|
||||
- For Python plugins you need the `pynvim` module. "Virtual envs" are recommended. After activating the virtual env do `pip install pynvim` (in *both*). Edit your `init.vim` so that it contains the path to the env's Python executable:
|
||||
```vim
|
||||
let g:python3_host_prog='C:/Users/foo/Envs/neovim3/Scripts/python.exe'
|
||||
- For Python plugins you need the `pynvim` module. Installation via uv
|
||||
(https://docs.astral.sh/uv/) is recommended; the `--upgrade` switch ensures
|
||||
installation of the latest version:
|
||||
```
|
||||
- Run `:checkhealth` and read `:help provider-python`.
|
||||
uv tool install --upgrade pynvim
|
||||
```
|
||||
- Run `:checkhealth` and read `:help provider-python` for more details.
|
||||
- **init.vim ("vimrc"):** If you already have Vim installed you can copy `%userprofile%\_vimrc` to `%userprofile%\AppData\Local\nvim\init.vim` to use your Vim config with Neovim.
|
||||
|
||||
|
||||
|
@@ -289,3 +289,8 @@ IV) It is not allowed to remove this license from the distribution of the Vim
|
||||
license for previous Vim releases instead of the license that they came
|
||||
with, at your option.
|
||||
|
||||
====
|
||||
|
||||
In addition, different license conditions may apply to some runtime files
|
||||
included with Vim; these will be specified in the header of each respective
|
||||
file.
|
||||
|
@@ -81,7 +81,7 @@ When a (non-experimental) feature is slated to be removed it should:
|
||||
as described for Lua features.
|
||||
- `vim.deprecate(…, 'x.y.z')` where major version `x` is greater than the
|
||||
current Nvim major version, is always treated as _soft_ deprecation.
|
||||
2. Be _hard_ deprecated in a following a release in which it was soft deprecated.
|
||||
2. Be _hard_ deprecated in a release following the release in which it was soft deprecated.
|
||||
- Use of the deprecated feature will still work but should issue a warning.
|
||||
- Features implemented in C will need bespoke implementations to communicate
|
||||
to users that the feature is deprecated.
|
||||
@@ -127,7 +127,9 @@ Some can be auto-bumped by `scripts/bump_deps.lua`.
|
||||
* [LuaJIT](https://github.com/LuaJIT/LuaJIT)
|
||||
* [Lua](https://www.lua.org/download.html)
|
||||
* [Luv](https://github.com/luvit/luv)
|
||||
* When bumping, also sync [our bundled documentation](https://github.com/neovim/neovim/blob/master/runtime/doc/luvref.txt) with [the upstream documentation](https://github.com/luvit/luv/blob/master/docs.md).
|
||||
* When bumping, also sync
|
||||
- [our bundled meta file](https://github.com/neovim/neovim/blob/master/runtime/lua/uv/_meta.lua) with [the upstream meta file](https://github.com/luvit/luv/blob/master/docs/meta.lua);
|
||||
- [our bundled documentation](https://github.com/neovim/neovim/blob/master/runtime/doc/luvref.txt) with [the upstream documentation](https://github.com/luvit/luv/blob/master/docs/docs.md).
|
||||
* [gettext](https://ftp.gnu.org/pub/gnu/gettext/)
|
||||
* [libiconv](https://ftp.gnu.org/pub/gnu/libiconv)
|
||||
* [libuv](https://github.com/libuv/libuv)
|
||||
@@ -152,7 +154,7 @@ These dependencies are "vendored" (inlined), we must update the sources manually
|
||||
* `src/nvim/tui/terminfo_defs.h`: terminfo definitions
|
||||
* Run `scripts/update_terminfo.sh` to update these definitions.
|
||||
* `runtime/lua/vim/lsp/_meta/protocol.lua`: LSP specification
|
||||
* Run `scripts/gen_lsp.lua` to update.
|
||||
* Run `src/gen/gen_lsp.lua` to update.
|
||||
* `runtime/lua/vim/_meta/lpeg.lua`: LPeg definitions.
|
||||
* Refer to [`LuaCATS/lpeg`](https://github.com/LuaCATS/lpeg) for updates.
|
||||
* Update the git SHA revision from which the documentation was taken.
|
||||
|
6
Makefile
6
Makefile
@@ -182,3 +182,9 @@ appimage-%:
|
||||
bash scripts/genappimage.sh $*
|
||||
|
||||
.PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST)
|
||||
|
||||
.PHONY: emmylua-check
|
||||
emmylua-check:
|
||||
-emmylua_check runtime/lua \
|
||||
--config .luarc.json \
|
||||
--config .emmyrc.json
|
||||
|
462
build.zig
Normal file
462
build.zig
Normal file
@@ -0,0 +1,462 @@
|
||||
const std = @import("std");
|
||||
const LazyPath = std.Build.LazyPath;
|
||||
const build_lua = @import("src/build_lua.zig");
|
||||
const gen = @import("src/gen/gen_steps.zig");
|
||||
const runtime = @import("runtime/gen_runtime.zig");
|
||||
const tests = @import("test/run_tests.zig");
|
||||
|
||||
const version = struct {
|
||||
const major = 0;
|
||||
const minor = 12;
|
||||
const patch = 0;
|
||||
const prerelease = "-dev";
|
||||
|
||||
const api_level = 14;
|
||||
const api_level_compat = 0;
|
||||
const api_prerelease = true;
|
||||
};
|
||||
|
||||
// TODO(bfredl): this is for an upstream issue
|
||||
pub fn lazyArtifact(d: *std.Build.Dependency, name: []const u8) ?*std.Build.Step.Compile {
|
||||
var found: ?*std.Build.Step.Compile = null;
|
||||
for (d.builder.install_tls.step.dependencies.items) |dep_step| {
|
||||
const inst = dep_step.cast(std.Build.Step.InstallArtifact) orelse continue;
|
||||
if (std.mem.eql(u8, inst.artifact.name, name)) {
|
||||
if (found != null) std.debug.panic("artifact name '{s}' is ambiguous", .{name});
|
||||
found = inst.artifact;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const t = target.result;
|
||||
const os_tag = t.os.tag;
|
||||
const is_windows = (os_tag == .windows);
|
||||
const is_linux = (os_tag == .linux);
|
||||
const is_darwin = os_tag.isDarwin();
|
||||
const modern_unix = is_darwin or os_tag.isBSD() or is_linux;
|
||||
|
||||
const cross_compiling = b.option(bool, "cross", "cross compile") orelse false;
|
||||
// TODO(bfredl): option to set nlua0 target explicitly when cross compiling?
|
||||
const target_host = if (cross_compiling) b.graph.host else target;
|
||||
const optimize_host = .ReleaseSafe;
|
||||
|
||||
// puc lua 5.1 is not ReleaseSafe "safe"
|
||||
const optimize_lua = if (optimize == .Debug or optimize == .ReleaseSafe) .ReleaseSmall else optimize;
|
||||
|
||||
const arch = t.cpu.arch;
|
||||
const default_luajit = (is_linux and arch == .x86_64) or (is_darwin and arch == .aarch64);
|
||||
const use_luajit = b.option(bool, "luajit", "use luajit") orelse default_luajit;
|
||||
const host_use_luajit = if (cross_compiling) false else use_luajit;
|
||||
const E = enum { luajit, lua51 };
|
||||
|
||||
const ziglua = b.dependency("zlua", .{
|
||||
.target = target,
|
||||
.optimize = optimize_lua,
|
||||
.lang = if (use_luajit) E.luajit else E.lua51,
|
||||
.shared = false,
|
||||
});
|
||||
|
||||
const ziglua_host = if (cross_compiling) b.dependency("zlua", .{
|
||||
.target = target_host,
|
||||
.optimize = optimize_lua,
|
||||
.lang = if (host_use_luajit) E.luajit else E.lua51,
|
||||
.shared = false,
|
||||
}) else ziglua;
|
||||
|
||||
const lpeg = b.dependency("lpeg", .{});
|
||||
|
||||
const iconv = if (is_windows or is_darwin) b.lazyDependency("libiconv", .{ .target = target, .optimize = optimize }) else null;
|
||||
|
||||
// this is currently not necessary, as ziglua currently doesn't use lazy dependencies
|
||||
// to circumvent ziglua.artifact() failing in a bad way.
|
||||
const lua = lazyArtifact(ziglua, "lua") orelse return;
|
||||
if (cross_compiling) {
|
||||
_ = lazyArtifact(ziglua_host, "lua") orelse return;
|
||||
}
|
||||
// const lua = ziglua.artifact("lua");
|
||||
|
||||
const libuv_dep = b.dependency("libuv", .{ .target = target, .optimize = optimize });
|
||||
const libuv = libuv_dep.artifact("uv");
|
||||
const libluv = try build_lua.build_libluv(b, target, optimize, lua, libuv);
|
||||
|
||||
const libluv_host = if (cross_compiling) libluv_host: {
|
||||
const libuv_dep_host = b.dependency("libuv", .{ .target = target_host, .optimize = optimize_host });
|
||||
const libuv_host = libuv_dep_host.artifact("uv");
|
||||
break :libluv_host try build_lua.build_libluv(b, target_host, optimize_host, ziglua_host.artifact("lua"), libuv_host);
|
||||
} else libluv;
|
||||
|
||||
const utf8proc = b.dependency("utf8proc", .{ .target = target, .optimize = optimize });
|
||||
const unibilium = b.dependency("unibilium", .{ .target = target, .optimize = optimize });
|
||||
// TODO(bfredl): fix upstream bugs with UBSAN
|
||||
const treesitter = b.dependency("treesitter", .{ .target = target, .optimize = .ReleaseFast });
|
||||
|
||||
const nlua0 = build_lua.build_nlua0(b, target_host, optimize_host, host_use_luajit, ziglua_host, lpeg, libluv_host);
|
||||
|
||||
// usual caveat emptor: might need to force a rebuild if the only change is
|
||||
// addition of new .c files, as those are not seen by any hash
|
||||
const subdirs = [_][]const u8{
|
||||
"", // src/nvim itself
|
||||
"os/",
|
||||
"api/",
|
||||
"api/private/",
|
||||
"msgpack_rpc/",
|
||||
"tui/",
|
||||
"tui/termkey/",
|
||||
"event/",
|
||||
"eval/",
|
||||
"lib/",
|
||||
"lua/",
|
||||
"viml/",
|
||||
"viml/parser/",
|
||||
"vterm/",
|
||||
};
|
||||
|
||||
// source names _relative_ src/nvim/, not including other src/ subdircs
|
||||
var nvim_sources = try std.ArrayList(gen.SourceItem).initCapacity(b.allocator, 100);
|
||||
var nvim_headers = try std.ArrayList([]u8).initCapacity(b.allocator, 100);
|
||||
|
||||
// both source headers and the {module}.h.generated.h files
|
||||
var api_headers = try std.ArrayList(std.Build.LazyPath).initCapacity(b.allocator, 10);
|
||||
|
||||
// TODO(bfredl): these should just become subdirs..
|
||||
const windows_only = [_][]const u8{ "pty_proc_win.c", "pty_proc_win.h", "pty_conpty_win.c", "pty_conpty_win.h", "os_win_console.c", "win_defs.h" };
|
||||
const unix_only = [_][]const u8{ "unix_defs.h", "pty_proc_unix.c", "pty_proc_unix.h" };
|
||||
const exclude_list = if (is_windows) &unix_only else &windows_only;
|
||||
|
||||
const src_dir = b.build_root.handle;
|
||||
for (subdirs) |s| {
|
||||
var dir = try src_dir.openDir(b.fmt("src/nvim/{s}", .{s}), .{ .iterate = true });
|
||||
defer dir.close();
|
||||
var it = dir.iterateAssumeFirstIteration();
|
||||
const api_export = std.mem.eql(u8, s, "api/");
|
||||
const os_check = std.mem.eql(u8, s, "os/");
|
||||
entries: while (try it.next()) |entry| {
|
||||
if (entry.name.len < 3) continue;
|
||||
if (entry.name[0] < 'a' or entry.name[0] > 'z') continue;
|
||||
if (os_check) {
|
||||
for (exclude_list) |name| {
|
||||
if (std.mem.eql(u8, name, entry.name)) {
|
||||
continue :entries;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) {
|
||||
try nvim_sources.append(.{ .name = b.fmt("{s}{s}", .{ s, entry.name }), .api_export = api_export });
|
||||
}
|
||||
if (std.mem.eql(u8, ".h", entry.name[entry.name.len - 2 ..])) {
|
||||
try nvim_headers.append(b.fmt("{s}{s}", .{ s, entry.name }));
|
||||
if (api_export and !std.mem.eql(u8, "ui_events.in.h", entry.name)) {
|
||||
try api_headers.append(b.path(b.fmt("src/nvim/{s}{s}", .{ s, entry.name })));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const support_unittests = use_luajit;
|
||||
|
||||
const gen_config = b.addWriteFiles();
|
||||
|
||||
const version_lua = gen_config.add("nvim_version.lua", lua_version_info(b));
|
||||
|
||||
var config_str = b.fmt("zig build -Doptimize={s}", .{@tagName(optimize)});
|
||||
if (cross_compiling) {
|
||||
config_str = b.fmt("{s} -Dcross -Dtarget={s} (host: {s})", .{ config_str, try t.linuxTriple(b.allocator), try b.graph.host.result.linuxTriple(b.allocator) });
|
||||
}
|
||||
|
||||
const versiondef_step = b.addConfigHeader(.{ .style = .{ .cmake = b.path("cmake.config/versiondef.h.in") } }, .{
|
||||
.NVIM_VERSION_MAJOR = version.major,
|
||||
.NVIM_VERSION_MINOR = version.minor,
|
||||
.NVIM_VERSION_PATCH = version.patch,
|
||||
.NVIM_VERSION_PRERELEASE = version.prerelease,
|
||||
.NVIM_VERSION_MEDIUM = "",
|
||||
.VERSION_STRING = "TODO", // TODO(bfredl): not sure what to put here. summary already in "config_str"
|
||||
.CONFIG = config_str,
|
||||
});
|
||||
_ = gen_config.addCopyFile(versiondef_step.getOutput(), "auto/versiondef.h"); // run_preprocessor() workaronnd
|
||||
|
||||
const ptrwidth = t.ptrBitWidth() / 8;
|
||||
const sysconfig_step = b.addConfigHeader(.{ .style = .{ .cmake = b.path("cmake.config/config.h.in") } }, .{
|
||||
.SIZEOF_INT = t.cTypeByteSize(.int),
|
||||
.SIZEOF_INTMAX_T = t.cTypeByteSize(.longlong), // TODO
|
||||
.SIZEOF_LONG = t.cTypeByteSize(.long),
|
||||
.SIZEOF_SIZE_T = ptrwidth,
|
||||
.SIZEOF_VOID_PTR = ptrwidth,
|
||||
|
||||
.PROJECT_NAME = "nvim",
|
||||
|
||||
.HAVE__NSGETENVIRON = is_darwin,
|
||||
.HAVE_FD_CLOEXEC = modern_unix,
|
||||
.HAVE_FSEEKO = modern_unix,
|
||||
.HAVE_LANGINFO_H = modern_unix,
|
||||
.HAVE_NL_LANGINFO_CODESET = modern_unix,
|
||||
.HAVE_NL_MSG_CAT_CNTR = t.isGnuLibC(),
|
||||
.HAVE_PWD_FUNCS = modern_unix,
|
||||
.HAVE_READLINK = modern_unix,
|
||||
.HAVE_STRNLEN = modern_unix,
|
||||
.HAVE_STRCASECMP = modern_unix,
|
||||
.HAVE_STRINGS_H = modern_unix,
|
||||
.HAVE_STRNCASECMP = modern_unix,
|
||||
.HAVE_STRPTIME = modern_unix,
|
||||
.HAVE_XATTR = is_linux,
|
||||
.HAVE_SYS_SDT_H = false,
|
||||
.HAVE_SYS_UTSNAME_H = modern_unix,
|
||||
.HAVE_SYS_WAIT_H = false, // unused
|
||||
.HAVE_TERMIOS_H = modern_unix,
|
||||
.HAVE_WORKING_LIBINTL = t.isGnuLibC(),
|
||||
.UNIX = modern_unix,
|
||||
.CASE_INSENSITIVE_FILENAME = is_darwin or is_windows,
|
||||
.HAVE_SYS_UIO_H = modern_unix,
|
||||
.HAVE_READV = modern_unix,
|
||||
.HAVE_DIRFD_AND_FLOCK = modern_unix,
|
||||
.HAVE_FORKPTY = modern_unix and !is_darwin, // also on Darwin but we lack the headers :(
|
||||
.HAVE_BE64TOH = modern_unix and !is_darwin,
|
||||
.ORDER_BIG_ENDIAN = t.cpu.arch.endian() == .big,
|
||||
.ENDIAN_INCLUDE_FILE = "endian.h",
|
||||
.HAVE_EXECINFO_BACKTRACE = modern_unix and !t.isMuslLibC(),
|
||||
.HAVE_BUILTIN_ADD_OVERFLOW = true,
|
||||
.HAVE_WIMPLICIT_FALLTHROUGH_FLAG = true,
|
||||
.HAVE_BITSCANFORWARD64 = null,
|
||||
|
||||
.VTERM_TEST_FILE = "test/vterm_test_output", // TODO(bfredl): revisit when porting libvterm tests
|
||||
});
|
||||
|
||||
_ = gen_config.addCopyFile(sysconfig_step.getOutput(), "auto/config.h"); // run_preprocessor() workaronnd
|
||||
_ = gen_config.add("auto/pathdef.h", b.fmt(
|
||||
\\char *default_vim_dir = "/usr/local/share/nvim";
|
||||
\\char *default_vimruntime_dir = "";
|
||||
\\char *default_lib_dir = "/usr/local/lib/nvim";
|
||||
, .{}));
|
||||
|
||||
// TODO(bfredl): include git version when available
|
||||
const medium = b.fmt("v{}.{}.{}{s}+zig", .{ version.major, version.minor, version.patch, version.prerelease });
|
||||
const versiondef_git = gen_config.add("auto/versiondef_git.h", b.fmt(
|
||||
\\#define NVIM_VERSION_MEDIUM "{s}"
|
||||
\\#define NVIM_VERSION_BUILD "???"
|
||||
\\
|
||||
, .{medium}));
|
||||
|
||||
// TODO(zig): using getEmittedIncludeTree() is ugly af. we want unittests
|
||||
// to reuse the std.build.Module include_path thing
|
||||
const unittest_include_path = [_]LazyPath{
|
||||
b.path("src/"),
|
||||
gen_config.getDirectory(),
|
||||
lua.getEmittedIncludeTree(),
|
||||
libuv.getEmittedIncludeTree(),
|
||||
libluv.getEmittedIncludeTree(),
|
||||
utf8proc.artifact("utf8proc").getEmittedIncludeTree(),
|
||||
unibilium.artifact("unibilium").getEmittedIncludeTree(),
|
||||
treesitter.artifact("tree-sitter").getEmittedIncludeTree(),
|
||||
if (iconv) |dep| dep.artifact("iconv").getEmittedIncludeTree() else b.path("UNUSED_PATH/"),
|
||||
};
|
||||
|
||||
const gen_headers, const funcs_data = try gen.nvim_gen_sources(b, nlua0, &nvim_sources, &nvim_headers, &api_headers, versiondef_git, version_lua);
|
||||
|
||||
const test_config_step = b.addWriteFiles();
|
||||
_ = test_config_step.add("test/cmakeconfig/paths.lua", try test_config(b));
|
||||
|
||||
const test_gen_step = b.step("gen_headers", "debug: output generated headers");
|
||||
const config_install = b.addInstallDirectory(.{ .source_dir = gen_config.getDirectory(), .install_dir = .prefix, .install_subdir = "config/" });
|
||||
test_gen_step.dependOn(&config_install.step);
|
||||
test_gen_step.dependOn(&b.addInstallDirectory(.{ .source_dir = gen_headers.getDirectory(), .install_dir = .prefix, .install_subdir = "headers/" }).step);
|
||||
|
||||
const nvim_exe = b.addExecutable(.{
|
||||
.name = "nvim",
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
nvim_exe.rdynamic = true; // -E
|
||||
|
||||
nvim_exe.linkLibrary(lua);
|
||||
nvim_exe.linkLibrary(libuv);
|
||||
nvim_exe.linkLibrary(libluv);
|
||||
if (iconv) |dep| nvim_exe.linkLibrary(dep.artifact("iconv"));
|
||||
nvim_exe.linkLibrary(utf8proc.artifact("utf8proc"));
|
||||
nvim_exe.linkLibrary(unibilium.artifact("unibilium"));
|
||||
nvim_exe.linkLibrary(treesitter.artifact("tree-sitter"));
|
||||
if (is_windows) {
|
||||
nvim_exe.linkSystemLibrary("netapi32");
|
||||
}
|
||||
nvim_exe.addIncludePath(b.path("src"));
|
||||
nvim_exe.addIncludePath(gen_config.getDirectory());
|
||||
nvim_exe.addIncludePath(gen_headers.getDirectory());
|
||||
build_lua.add_lua_modules(nvim_exe.root_module, lpeg, use_luajit, false);
|
||||
|
||||
var unit_test_sources = try std.ArrayList([]u8).initCapacity(b.allocator, 10);
|
||||
if (support_unittests) {
|
||||
var unit_test_fixtures = try src_dir.openDir("test/unit/fixtures/", .{ .iterate = true });
|
||||
defer unit_test_fixtures.close();
|
||||
var it = unit_test_fixtures.iterateAssumeFirstIteration();
|
||||
while (try it.next()) |entry| {
|
||||
if (entry.name.len < 3) continue;
|
||||
if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) {
|
||||
try unit_test_sources.append(b.fmt("test/unit/fixtures/{s}", .{entry.name}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const src_paths = try b.allocator.alloc([]u8, nvim_sources.items.len + unit_test_sources.items.len);
|
||||
for (nvim_sources.items, 0..) |s, i| {
|
||||
src_paths[i] = b.fmt("src/nvim/{s}", .{s.name});
|
||||
}
|
||||
@memcpy(src_paths[nvim_sources.items.len..], unit_test_sources.items);
|
||||
|
||||
const flags = [_][]const u8{
|
||||
"-std=gnu99",
|
||||
"-DZIG_BUILD",
|
||||
"-D_GNU_SOURCE",
|
||||
if (support_unittests) "-DUNIT_TESTING" else "",
|
||||
if (use_luajit) "" else "-DNVIM_VENDOR_BIT",
|
||||
if (is_windows) "-DMSWIN" else "",
|
||||
if (is_windows) "-DWIN32_LEAN_AND_MEAN" else "",
|
||||
if (is_windows) "-DUTF8PROC_STATIC" else "",
|
||||
};
|
||||
nvim_exe.addCSourceFiles(.{ .files = src_paths, .flags = &flags });
|
||||
|
||||
nvim_exe.addCSourceFiles(.{ .files = &.{
|
||||
"src/xdiff/xdiffi.c",
|
||||
"src/xdiff/xemit.c",
|
||||
"src/xdiff/xhistogram.c",
|
||||
"src/xdiff/xpatience.c",
|
||||
"src/xdiff/xprepare.c",
|
||||
"src/xdiff/xutils.c",
|
||||
"src/cjson/lua_cjson.c",
|
||||
"src/cjson/fpconv.c",
|
||||
"src/cjson/strbuf.c",
|
||||
}, .flags = &flags });
|
||||
|
||||
const nvim_exe_step = b.step("nvim_bin", "only the binary (not a fully working install!)");
|
||||
const nvim_exe_install = b.addInstallArtifact(nvim_exe, .{});
|
||||
|
||||
nvim_exe_step.dependOn(&nvim_exe_install.step);
|
||||
|
||||
const gen_runtime = try runtime.nvim_gen_runtime(b, nlua0, funcs_data);
|
||||
const runtime_install = b.addInstallDirectory(.{ .source_dir = gen_runtime.getDirectory(), .install_dir = .prefix, .install_subdir = "runtime/" });
|
||||
|
||||
const nvim = b.step("nvim", "build the editor");
|
||||
|
||||
nvim.dependOn(&nvim_exe_install.step);
|
||||
nvim.dependOn(&runtime_install.step);
|
||||
|
||||
const lua_dev_deps = b.dependency("lua_dev_deps", .{});
|
||||
|
||||
const test_deps = b.step("test_deps", "test prerequisites");
|
||||
test_deps.dependOn(&nvim_exe_install.step);
|
||||
test_deps.dependOn(&runtime_install.step);
|
||||
|
||||
test_deps.dependOn(test_fixture(b, "shell-test", null, target, optimize));
|
||||
test_deps.dependOn(test_fixture(b, "tty-test", libuv, target, optimize));
|
||||
test_deps.dependOn(test_fixture(b, "pwsh-test", null, target, optimize));
|
||||
test_deps.dependOn(test_fixture(b, "printargs-test", null, target, optimize));
|
||||
test_deps.dependOn(test_fixture(b, "printenv-test", null, target, optimize));
|
||||
test_deps.dependOn(test_fixture(b, "streams-test", libuv, target, optimize));
|
||||
|
||||
const parser_c = b.dependency("treesitter_c", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "c", parser_c.path("."), false, target, optimize));
|
||||
const parser_markdown = b.dependency("treesitter_markdown", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "markdown", parser_markdown.path("tree-sitter-markdown/"), true, target, optimize));
|
||||
test_deps.dependOn(add_ts_parser(b, "markdown_inline", parser_markdown.path("tree-sitter-markdown-inline/"), true, target, optimize));
|
||||
const parser_vim = b.dependency("treesitter_vim", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "vim", parser_vim.path("."), true, target, optimize));
|
||||
const parser_vimdoc = b.dependency("treesitter_vimdoc", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "vimdoc", parser_vimdoc.path("."), false, target, optimize));
|
||||
const parser_lua = b.dependency("treesitter_lua", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "lua", parser_lua.path("."), true, target, optimize));
|
||||
const parser_query = b.dependency("treesitter_query", .{ .target = target, .optimize = optimize });
|
||||
test_deps.dependOn(add_ts_parser(b, "query", parser_query.path("."), false, target, optimize));
|
||||
|
||||
const unit_headers: ?[]const LazyPath = if (support_unittests) &(unittest_include_path ++ .{gen_headers.getDirectory()}) else null;
|
||||
|
||||
try tests.test_steps(b, nvim_exe, test_deps, lua_dev_deps.path("."), test_config_step.getDirectory(), unit_headers);
|
||||
}
|
||||
|
||||
pub fn test_fixture(
|
||||
b: *std.Build,
|
||||
name: []const u8,
|
||||
libuv: ?*std.Build.Step.Compile,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
) *std.Build.Step {
|
||||
const fixture = b.addExecutable(.{
|
||||
.name = name,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
const source = if (std.mem.eql(u8, name, "pwsh-test")) "shell-test" else name;
|
||||
fixture.addCSourceFile(.{ .file = b.path(b.fmt("./test/functional/fixtures/{s}.c", .{source})) });
|
||||
fixture.linkLibC();
|
||||
if (libuv) |uv| fixture.linkLibrary(uv);
|
||||
return &b.addInstallArtifact(fixture, .{}).step;
|
||||
}
|
||||
|
||||
pub fn add_ts_parser(
|
||||
b: *std.Build,
|
||||
name: []const u8,
|
||||
parser_dir: LazyPath,
|
||||
scanner: bool,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
) *std.Build.Step {
|
||||
const parser = b.addLibrary(.{
|
||||
.name = name,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
.linkage = .dynamic,
|
||||
});
|
||||
parser.addCSourceFile(.{ .file = parser_dir.path(b, "src/parser.c") });
|
||||
if (scanner) parser.addCSourceFile(.{ .file = parser_dir.path(b, "src/scanner.c") });
|
||||
parser.addIncludePath(parser_dir.path(b, "src"));
|
||||
parser.linkLibC();
|
||||
|
||||
const parser_install = b.addInstallArtifact(parser, .{ .dest_sub_path = b.fmt("parser/{s}.so", .{name}) });
|
||||
return &parser_install.step;
|
||||
}
|
||||
|
||||
pub fn lua_version_info(b: *std.Build) []u8 {
|
||||
const v = version;
|
||||
return b.fmt(
|
||||
\\return {{
|
||||
\\ {{"major", {}}},
|
||||
\\ {{"minor", {}}},
|
||||
\\ {{"patch", {}}},
|
||||
\\ {{"prerelease", {}}},
|
||||
\\ {{"api_level", {}}},
|
||||
\\ {{"api_compatible", {}}},
|
||||
\\ {{"api_prerelease", {}}},
|
||||
\\}}
|
||||
, .{ v.major, v.minor, v.patch, v.prerelease.len > 0, v.api_level, v.api_level_compat, v.api_prerelease });
|
||||
}
|
||||
|
||||
pub fn test_config(b: *std.Build) ![]u8 {
|
||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const src_path = try b.build_root.handle.realpath(".", &buf);
|
||||
|
||||
// we don't use test/cmakeconfig/paths.lua.in because it contains cmake specific logic
|
||||
return b.fmt(
|
||||
\\local M = {{}}
|
||||
\\
|
||||
\\M.apple_sysroot = ""
|
||||
\\M.translations_enabled = "$ENABLE_TRANSLATIONS" == "ON"
|
||||
\\M.is_asan = "$ENABLE_ASAN_UBSAN" == "ON"
|
||||
\\M.is_zig_build = true
|
||||
\\M.vterm_test_file = "test/vterm_test_output"
|
||||
\\M.test_build_dir = "{[bin_dir]s}" -- bull
|
||||
\\M.test_source_path = "{[src_path]s}"
|
||||
\\M.test_lua_prg = ""
|
||||
\\M.test_luajit_prg = ""
|
||||
\\ -- include path passed on the cmdline, see test/lua_runner.lua
|
||||
\\M.include_paths = _G.c_include_path or {{}}
|
||||
\\
|
||||
\\return M
|
||||
, .{ .bin_dir = b.install_path, .src_path = src_path });
|
||||
}
|
72
build.zig.zon
Normal file
72
build.zig.zon
Normal file
@@ -0,0 +1,72 @@
|
||||
.{
|
||||
.name = .neovim,
|
||||
.fingerprint = 0x66eb090879307a38,
|
||||
.version = "0.12.0",
|
||||
.minimum_zig_version = "0.14.0",
|
||||
|
||||
.dependencies = .{
|
||||
.zlua = .{
|
||||
.url = "git+https://github.com/natecraddock/ziglua#6889b2d90ee6ae96810a9f04ec7c62d9aa91d088",
|
||||
.hash = "zlua-0.1.0-hGRpCxctBQDEQgDArJ0Kc4RDIsD-Hw3pw9pPPw_kGmmY",
|
||||
},
|
||||
.lpeg = .{
|
||||
.url = "https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz",
|
||||
.hash = "N-V-__8AAMnaAwCEutreuREG3QayBVEZqUTDQFY1Nsrv2OIt",
|
||||
},
|
||||
.luv = .{
|
||||
.url = "git+https://github.com/luvit/luv?ref=1.51.0-1#4c9fbc6cf6f3338bb0e0426710cf885ee557b540",
|
||||
.hash = "N-V-__8AAMlNDwCY07jUoMiq3iORXdZy0uFWKiHsy8MaDBJA",
|
||||
},
|
||||
.lua_compat53 = .{
|
||||
.url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.13.tar.gz",
|
||||
.hash = "N-V-__8AADi-AwDnVoXwDCQvv2wcYOmN0bJLqZ44J3lwoQY2",
|
||||
},
|
||||
.treesitter = .{
|
||||
.url = "git+https://github.com/tree-sitter/tree-sitter#d87921bb9c39b0b06c811f2082f9a9991cdca027",
|
||||
.hash = "tree_sitter-0.26.0-Tw2sRxO7CwC0NyDrSygSi7UXRHMNUFEF8GRq6dK81lRF",
|
||||
},
|
||||
.libuv = .{
|
||||
.url = "git+https://github.com/allyourcodebase/libuv#a2dfd385bd2a00d6d290fda85a40a55a9d6cffc5",
|
||||
.hash = "libuv-1.51.0-htqqv6liAADxBLIBCZT-qUh_3nRRwtNYsOFQOUmrd_sx",
|
||||
},
|
||||
.utf8proc = .{ .path = "./deps/utf8proc/" },
|
||||
.unibilium = .{ .path = "./deps/unibilium/" },
|
||||
.libiconv = .{
|
||||
.url = "git+https://github.com/allyourcodebase/libiconv#9def4c8a1743380e85bcedb80f2c15b455e236f3",
|
||||
.hash = "libiconv-1.18.0-p9sJwWnqAACzVYeWgXB5r5lOQ74XwTPlptixV0JPRO28",
|
||||
.lazy = true,
|
||||
},
|
||||
.lua_dev_deps = .{
|
||||
.url = "https://github.com/neovim/deps/raw/06ef2b58b0876f8de1a3f5a710473dcd7afff251/opt/lua-dev-deps.tar.gz",
|
||||
.hash = "N-V-__8AAGevEQCHAkCozca5AIdN9DFc3Luf3g3r2AcbyOrm",
|
||||
},
|
||||
.treesitter_c = .{
|
||||
.url = "git+https://github.com/tree-sitter/tree-sitter-c?ref=v0.24.1#7fa1be1b694b6e763686793d97da01f36a0e5c12",
|
||||
.hash = "N-V-__8AANxPSABzw3WBTSH_YkwaGAfrK6PBqAMqQedkDDim",
|
||||
},
|
||||
.treesitter_markdown = .{
|
||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-markdown?ref=v0.5.0#afaa4138517363362f54c89330c9d79391e81168",
|
||||
.hash = "N-V-__8AAIIZUwD3CGdyI2DiHu7Suj2jIF_EAVlM6REFGwju",
|
||||
},
|
||||
.treesitter_lua = .{
|
||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-lua?ref=v0.4.0#4569d1c361129e71a205b94a05e158bd71b1709f",
|
||||
.hash = "N-V-__8AAEF5CABqSL9zqc03aQsT6Nni54ZCcL98pnuDL2D3",
|
||||
},
|
||||
.treesitter_vim = .{
|
||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-vim?ref=v0.7.0#3dd4747082d1b717b8978211c06ef7b6cd16125b",
|
||||
.hash = "N-V-__8AAMArVAB4uo2wg2XRs8HBviQ4Pq366cC_iRolX4Vc",
|
||||
},
|
||||
.treesitter_vimdoc = .{
|
||||
.url = "git+https://github.com/neovim/tree-sitter-vimdoc?ref=v4.0.0#9f6191a98702edc1084245abd5523279d4b681fb",
|
||||
.hash = "N-V-__8AAI4YCgD7OqxCEAmz2RqT_ohl6eA4F0fGMtLIe7nb",
|
||||
},
|
||||
.treesitter_query = .{
|
||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-query?ref=v0.6.2#8a43889f89fd0667289936341bff3a77bafade17",
|
||||
.hash = "N-V-__8AAARLBACBLGiXGFTijEzLv8AwiqT_kJpmVjir1BgX",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
// TODO(bfredl): explicitly list the subdirs which actually are used
|
||||
"",
|
||||
},
|
||||
}
|
@@ -12,6 +12,10 @@
|
||||
#endif
|
||||
|
||||
#define NVIM_VERSION_CFLAGS "${VERSION_STRING}"
|
||||
#define NVIM_VERSION_BUILD_TYPE "$<CONFIG>"
|
||||
#ifdef ZIG_BUILD
|
||||
# define NVIM_VERSION_BUILD_TYPE "${CONFIG}"
|
||||
#else
|
||||
# define NVIM_VERSION_BUILD_TYPE "$<CONFIG>"
|
||||
#endif
|
||||
|
||||
#endif // AUTO_VERSIONDEF_H
|
||||
|
@@ -73,7 +73,7 @@ if(HAS_OG_FLAG)
|
||||
set(DEFAULT_MAKE_CFLAGS CFLAGS+=-Og ${DEFAULT_MAKE_CFLAGS})
|
||||
endif()
|
||||
|
||||
set(DEPS_INCLUDE_FLAGS "-I${DEPS_INSTALL_DIR}/include -I${DEPS_INSTALL_DIR}/include/luajit-2.1")
|
||||
set(DEPS_INCLUDE_FLAGS "-I\"${DEPS_INSTALL_DIR}/include\" -I\"${DEPS_INSTALL_DIR}/include/luajit-2.1\"")
|
||||
|
||||
# If the macOS deployment target is not set manually (via $MACOSX_DEPLOYMENT_TARGET),
|
||||
# fall back to local system version. Needs to be done here and in top-level CMakeLists.txt.
|
||||
@@ -96,10 +96,10 @@ else()
|
||||
find_package(Lua 5.1 EXACT)
|
||||
if(LUAJIT_FOUND)
|
||||
set(LUA_ENGINE LuaJit)
|
||||
string(APPEND DEPS_INCLUDE_FLAGS " -I${LUAJIT_INCLUDE_DIR}")
|
||||
string(APPEND DEPS_INCLUDE_FLAGS " -I\"${LUAJIT_INCLUDE_DIR}\"")
|
||||
elseif(LUA_FOUND)
|
||||
set(LUA_ENGINE Lua)
|
||||
string(APPEND DEPS_INCLUDE_FLAGS " -I${LUA_INCLUDE_DIR}")
|
||||
string(APPEND DEPS_INCLUDE_FLAGS " -I\"${LUA_INCLUDE_DIR}\"")
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find system lua or luajit")
|
||||
endif()
|
||||
|
@@ -42,7 +42,7 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
BuildLuaJit(INSTALL_COMMAND ${BUILDCMD_UNIX}
|
||||
BuildLuajit(INSTALL_COMMAND ${BUILDCMD_UNIX}
|
||||
CC=${DEPS_C_COMPILER} PREFIX=${DEPS_INSTALL_DIR}
|
||||
${DEPLOYMENT_TARGET} install)
|
||||
|
||||
@@ -53,7 +53,7 @@ elseif(MINGW)
|
||||
else()
|
||||
set(LUAJIT_MAKE_PRG ${CMAKE_MAKE_PROGRAM})
|
||||
endif()
|
||||
BuildLuaJit(BUILD_COMMAND ${LUAJIT_MAKE_PRG} CC=${DEPS_C_COMPILER}
|
||||
BuildLuajit(BUILD_COMMAND ${LUAJIT_MAKE_PRG} CC=${DEPS_C_COMPILER}
|
||||
PREFIX=${DEPS_INSTALL_DIR}
|
||||
CFLAGS+=-DLUA_USE_APICHECK
|
||||
CFLAGS+=-funwind-tables
|
||||
@@ -75,7 +75,7 @@ elseif(MINGW)
|
||||
)
|
||||
elseif(MSVC)
|
||||
|
||||
BuildLuaJit(
|
||||
BuildLuajit(
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E chdir ${DEPS_BUILD_DIR}/src/luajit/src ${DEPS_BUILD_DIR}/src/luajit/src/msvcbuild.bat
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/luajit.exe ${DEPS_BIN_DIR}
|
||||
|
@@ -7,5 +7,6 @@ ExternalProject_Add(wasmtime
|
||||
-D WASMTIME_FASTEST_RUNTIME=ON # build with full LTO
|
||||
-D WASMTIME_DISABLE_ALL_FEATURES=ON # don't need all that crap...
|
||||
-D WASMTIME_FEATURE_CRANELIFT=ON # ...except this one (compiles wasm to platform code)
|
||||
-D WASMTIME_FEATURE_GC_DRC=ON # ...and this one (needed by ts to create engines)
|
||||
USES_TERMINAL_BUILD TRUE
|
||||
${EXTERNALPROJECT_OPTIONS})
|
||||
|
@@ -1,8 +1,8 @@
|
||||
LIBUV_URL https://github.com/libuv/libuv/archive/v1.50.0.tar.gz
|
||||
LIBUV_SHA256 b1ec56444ee3f1e10c8bd3eed16ba47016ed0b94fe42137435aaf2e0bd574579
|
||||
LIBUV_URL https://github.com/libuv/libuv/archive/v1.51.0.tar.gz
|
||||
LIBUV_SHA256 27e55cf7083913bfb6826ca78cde9de7647cded648d35f24163f2d31bb9f51cd
|
||||
|
||||
LUAJIT_URL https://github.com/luajit/luajit/archive/538a82133ad6fddfd0ca64de167c4aca3bc1a2da.tar.gz
|
||||
LUAJIT_SHA256 7acbc36be8f21072422eb9a5e5fc468d0eaa55bec1b70260d651e845684621e2
|
||||
LUAJIT_URL https://github.com/luajit/luajit/archive/871db2c84ecefd70a850e03a6c340214a81739f0.tar.gz
|
||||
LUAJIT_SHA256 ab3f16d82df6946543565cfb0d2810d387d79a3a43e0431695b03466188e2680
|
||||
|
||||
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
|
||||
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
||||
@@ -10,8 +10,8 @@ LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
||||
UNIBILIUM_URL https://github.com/neovim/unibilium/archive/v2.1.2.tar.gz
|
||||
UNIBILIUM_SHA256 370ecb07fbbc20d91d1b350c55f1c806b06bf86797e164081ccc977fc9b3af7a
|
||||
|
||||
LUV_URL https://github.com/luvit/luv/archive/1.50.0-1.tar.gz
|
||||
LUV_SHA256 bb4f0570571e40c1d2a7644f6f9c1309a6ccdb19bf4d397e8d7bfd0c6b88e613
|
||||
LUV_URL https://github.com/luvit/luv/archive/1.51.0-1.tar.gz
|
||||
LUV_SHA256 d4a11178ae8e16ba5886799ea91905dd9b0b479c75aebd67866d37373e41526f
|
||||
|
||||
LPEG_URL https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz
|
||||
LPEG_SHA256 4b155d67d2246c1ffa7ad7bc466c1ea899bbc40fef0257cc9c03cecbaed4352a
|
||||
@@ -34,25 +34,25 @@ LIBICONV_SHA256 8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313
|
||||
UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/v2.10.0.tar.gz
|
||||
UTF8PROC_SHA256 6f4f1b639daa6dca9f80bc5db1233e9cbaa31a67790887106160b33ef743f136
|
||||
|
||||
TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.23.4.tar.gz
|
||||
TREESITTER_C_SHA256 b66c5043e26d84e5f17a059af71b157bcf202221069ed220aa1696d7d1d28a7a
|
||||
TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.3.0.tar.gz
|
||||
TREESITTER_LUA_SHA256 a34cc70abfd8d2d4b0fabf01403ea05f848e1a4bc37d8a4bfea7164657b35d31
|
||||
TREESITTER_VIM_URL https://github.com/tree-sitter-grammars/tree-sitter-vim/archive/v0.5.0.tar.gz
|
||||
TREESITTER_VIM_SHA256 90019d12d2da0751c027124f27f5335babf069a050457adaed53693b5e9cf10a
|
||||
TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v3.0.1.tar.gz
|
||||
TREESITTER_VIMDOC_SHA256 76b65e5bee9ff78eb21256619b1995aac4d80f252c19e1c710a4839481ded09e
|
||||
TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.5.1.tar.gz
|
||||
TREESITTER_QUERY_SHA256 fe8c712880a529d454347cd4c58336ac2db22243bae5055bdb5844fb3ea56192
|
||||
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.4.1.tar.gz
|
||||
TREESITTER_MARKDOWN_SHA256 e0fdb2dca1eb3063940122e1475c9c2b069062a638c95939e374c5427eddee9f
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.25.3.tar.gz
|
||||
TREESITTER_SHA256 862fac52653bc7bc9d2cd0630483e6bdf3d02bcd23da956ca32663c4798a93e3
|
||||
TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.24.1.tar.gz
|
||||
TREESITTER_C_SHA256 25dd4bb3dec770769a407e0fc803f424ce02c494a56ce95fedc525316dcf9b48
|
||||
TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.4.0.tar.gz
|
||||
TREESITTER_LUA_SHA256 b0977aced4a63bb75f26725787e047b8f5f4a092712c840ea7070765d4049559
|
||||
TREESITTER_VIM_URL https://github.com/tree-sitter-grammars/tree-sitter-vim/archive/v0.7.0.tar.gz
|
||||
TREESITTER_VIM_SHA256 44eabc31127c4feacda19f2a05a5788272128ff561ce01093a8b7a53aadcc7b2
|
||||
TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v4.0.0.tar.gz
|
||||
TREESITTER_VIMDOC_SHA256 8096794c0f090b2d74b7bff94548ac1be3285b929ec74f839bd9b3ff4f4c6a0b
|
||||
TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.6.2.tar.gz
|
||||
TREESITTER_QUERY_SHA256 90682e128d048fbf2a2a17edca947db71e326fa0b3dba4136e041e096538b4eb
|
||||
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.5.0.tar.gz
|
||||
TREESITTER_MARKDOWN_SHA256 14c2c948ccf0e9b606eec39b09286c59dddf28307849f71b7ce2b1d1ef06937e
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.25.8.tar.gz
|
||||
TREESITTER_SHA256 178b575244d967f4920a4642408dc4edf6de96948d37d7f06e5b78acee9c0b4e
|
||||
|
||||
WASMTIME_URL https://github.com/bytecodealliance/wasmtime/archive/v29.0.1.tar.gz
|
||||
WASMTIME_SHA256 b94b6c6fd6aebaf05d4c69c1b12b5dc217b0d42c1a95f435b33af63dddfa5304
|
||||
|
||||
UNCRUSTIFY_URL https://github.com/uncrustify/uncrustify/archive/uncrustify-0.80.1.tar.gz
|
||||
UNCRUSTIFY_SHA256 0e2616ec2f78e12816388c513f7060072ff7942b42f1175eb28b24cb75aaec48
|
||||
UNCRUSTIFY_URL https://github.com/uncrustify/uncrustify/archive/uncrustify-0.81.0.tar.gz
|
||||
UNCRUSTIFY_SHA256 484623dc16b92206adc6ac0770077c6c67c6e441102148c2a121a19549330ff9
|
||||
LUA_DEV_DEPS_URL https://github.com/neovim/deps/raw/06ef2b58b0876f8de1a3f5a710473dcd7afff251/opt/lua-dev-deps.tar.gz
|
||||
LUA_DEV_DEPS_SHA256 49f8399e453103064a23c65534f266f3067cda716b6502f016bfafeed5799354
|
||||
|
@@ -7,6 +7,7 @@ set(ENV{XDG_DATA_HOME} ${BUILD_DIR}/Xtest_xdg/share)
|
||||
set(ENV{XDG_STATE_HOME} ${BUILD_DIR}/Xtest_xdg/state)
|
||||
unset(ENV{XDG_DATA_DIRS})
|
||||
unset(ENV{NVIM}) # Clear $NVIM in case tests are running from Nvim. #11009
|
||||
unset(ENV{TMUX}) # Nvim TUI shouldn't think it's running in tmux. #34173
|
||||
|
||||
# TODO(dundargoc): The CIRRUS_CI environment variable isn't passed to here from
|
||||
# the main CMakeLists.txt, so we have to manually pass it to this script and
|
||||
@@ -68,7 +69,7 @@ endif()
|
||||
execute_process(
|
||||
# Note: because of "-ll" (low-level interpreter mode), some modules like
|
||||
# _editor.lua are not loaded.
|
||||
COMMAND ${NVIM_PRG} -ll ${WORKING_DIR}/test/lua_runner.lua ${DEPS_INSTALL_DIR} busted -v -o test.busted.outputHandlers.nvim
|
||||
COMMAND ${NVIM_PRG} -ll ${WORKING_DIR}/test/lua_runner.lua ${DEPS_INSTALL_DIR}/share/lua/5.1/ busted -v -o test.busted.outputHandlers.nvim
|
||||
--lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua
|
||||
--lpath=${BUILD_DIR}/?.lua
|
||||
--lpath=${WORKING_DIR}/src/?.lua
|
||||
@@ -78,7 +79,6 @@ execute_process(
|
||||
${TEST_PATH}
|
||||
TIMEOUT $ENV{TEST_TIMEOUT}
|
||||
WORKING_DIRECTORY ${WORKING_DIR}
|
||||
ERROR_VARIABLE err
|
||||
RESULT_VARIABLE res
|
||||
${EXTRA_ARGS})
|
||||
|
||||
@@ -87,11 +87,6 @@ file(REMOVE_RECURSE ${RM_FILES})
|
||||
|
||||
if(res)
|
||||
message(STATUS "Tests exited non-zero: ${res}")
|
||||
if("${err}" STREQUAL "")
|
||||
message(STATUS "No output to stderr.")
|
||||
else()
|
||||
message(STATUS "Output to stderr:\n${err}")
|
||||
endif()
|
||||
|
||||
# Dump the logfile on CI (if not displayed and moved already).
|
||||
if(CI_BUILD)
|
||||
|
30
deps/unibilium/build.zig
vendored
Normal file
30
deps/unibilium/build.zig
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const upstream = b.dependency("unibilium", .{});
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "unibilium",
|
||||
.linkage = .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
|
||||
lib.installHeader(upstream.path("unibilium.h"), "unibilium.h");
|
||||
|
||||
lib.linkLibC();
|
||||
|
||||
lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{
|
||||
"unibilium.c",
|
||||
"uninames.c",
|
||||
"uniutil.c",
|
||||
}, .flags = &.{"-DTERMINFO_DIRS=\"/etc/terminfo:/usr/share/terminfo\""} });
|
||||
|
||||
b.installArtifact(lib);
|
||||
}
|
12
deps/unibilium/build.zig.zon
vendored
Normal file
12
deps/unibilium/build.zig.zon
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.{
|
||||
.name = "unibilium",
|
||||
.version = "2.1.2",
|
||||
.paths = .{""},
|
||||
|
||||
.dependencies = .{
|
||||
.unibilium = .{
|
||||
.url = "git+https://github.com/neovim/unibilium?ref=v2.1.2#bfcb0350129dd76893bc90399cf37c45812268a2",
|
||||
.hash = "N-V-__8AADO1CgCggvx73yptnBlXbEm7TjOSO6VGIqc0CvYR",
|
||||
},
|
||||
},
|
||||
}
|
27
deps/utf8proc/build.zig
vendored
Normal file
27
deps/utf8proc/build.zig
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const upstream = b.dependency("utf8proc", .{});
|
||||
const lib = b.addLibrary(.{
|
||||
.name = "utf8proc",
|
||||
.linkage = .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
lib.installHeader(upstream.path("utf8proc.h"), "utf8proc.h");
|
||||
|
||||
lib.linkLibC();
|
||||
|
||||
lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{
|
||||
"utf8proc.c",
|
||||
}, .flags = &.{"-DUTF8PROC_STATIC"} });
|
||||
|
||||
b.installArtifact(lib);
|
||||
}
|
12
deps/utf8proc/build.zig.zon
vendored
Normal file
12
deps/utf8proc/build.zig.zon
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
.{
|
||||
.name = "utf8proc",
|
||||
.version = "2.10.0",
|
||||
.paths = .{""},
|
||||
|
||||
.dependencies = .{
|
||||
.utf8proc = .{
|
||||
.url = "git+https://github.com/JuliaStrings/utf8proc?ref=v2.10.0#a1b99daa2a3393884220264c927a48ba1251a9c6",
|
||||
.hash = "N-V-__8AAPJfKADYDOC95xuKyudrlob6eFqgzfFl8NbpOoU9",
|
||||
},
|
||||
},
|
||||
}
|
@@ -12,12 +12,17 @@ get_directory_property(LUA_GEN_DEPS DIRECTORY ${PROJECT_SOURCE_DIR}/src/nvim DEF
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_SYN_VIM}
|
||||
COMMAND ${LUA_GEN} ${SYN_VIM_GENERATOR} ${GENERATED_SYN_VIM} ${FUNCS_DATA}
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/options.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/vvars.lua
|
||||
DEPENDS
|
||||
${LUA_GEN_DEPS}
|
||||
${SYN_VIM_GENERATOR}
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/options.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/vvars.lua
|
||||
${PROJECT_SOURCE_DIR}/src/nvim/eval.c
|
||||
${FUNCS_DATA}
|
||||
)
|
||||
|
@@ -1,859 +0,0 @@
|
||||
----------------------------------------
|
||||
-- This file is generated via github.com/tjdevries/vim9jit
|
||||
-- For any bugs, please first consider reporting there.
|
||||
----------------------------------------
|
||||
|
||||
-- Ignore "value assigned to a local variable is unused" because
|
||||
-- we can't guarantee that local variables will be used by plugins
|
||||
-- luacheck: ignore
|
||||
--- @diagnostic disable
|
||||
|
||||
local vim9 = require('_vim9script')
|
||||
local M = {}
|
||||
local prepended = nil
|
||||
local grepCache = nil
|
||||
local Complete = nil
|
||||
local GetAddition = nil
|
||||
local Tag2item = nil
|
||||
local Dict2info = nil
|
||||
local ParseTagline = nil
|
||||
local Tagline2item = nil
|
||||
local Tagcmd2extra = nil
|
||||
local Nextitem = nil
|
||||
local StructMembers = nil
|
||||
local SearchMembers = nil
|
||||
-- vim9script
|
||||
|
||||
-- # Vim completion script
|
||||
-- # Language: C
|
||||
-- # Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||
-- # Last Change: 2023 Aug 10
|
||||
-- # Rewritten in Vim9 script by github user lacygoill
|
||||
-- # Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
|
||||
prepended = ''
|
||||
grepCache = vim.empty_dict()
|
||||
|
||||
-- # This function is used for the 'omnifunc' option.
|
||||
|
||||
Complete = function(findstart, abase)
|
||||
findstart = vim9.bool(findstart)
|
||||
if vim9.bool(findstart) then
|
||||
-- # Locate the start of the item, including ".", "->" and "[...]".
|
||||
local line = vim9.fn.getline('.')
|
||||
local start = vim9.fn.charcol('.') - 1
|
||||
local lastword = -1
|
||||
while start > 0 do
|
||||
if vim9.ops.RegexpMatches(vim9.index(line, vim9.ops.Minus(start, 1)), '\\w') then
|
||||
start = start - 1
|
||||
elseif
|
||||
vim9.bool(vim9.ops.RegexpMatches(vim9.index(line, vim9.ops.Minus(start, 1)), '\\.'))
|
||||
then
|
||||
if lastword == -1 then
|
||||
lastword = start
|
||||
end
|
||||
start = start - 1
|
||||
elseif
|
||||
vim9.bool(
|
||||
start > 1
|
||||
and vim9.index(line, vim9.ops.Minus(start, 2)) == '-'
|
||||
and vim9.index(line, vim9.ops.Minus(start, 1)) == '>'
|
||||
)
|
||||
then
|
||||
if lastword == -1 then
|
||||
lastword = start
|
||||
end
|
||||
start = vim9.ops.Minus(start, 2)
|
||||
elseif vim9.bool(vim9.index(line, vim9.ops.Minus(start, 1)) == ']') then
|
||||
-- # Skip over [...].
|
||||
local n = 0
|
||||
start = start - 1
|
||||
while start > 0 do
|
||||
start = start - 1
|
||||
if vim9.index(line, start) == '[' then
|
||||
if n == 0 then
|
||||
break
|
||||
end
|
||||
n = n - 1
|
||||
elseif vim9.bool(vim9.index(line, start) == ']') then
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- # Return the column of the last word, which is going to be changed.
|
||||
-- # Remember the text that comes before it in prepended.
|
||||
if lastword == -1 then
|
||||
prepended = ''
|
||||
return vim9.fn.byteidx(line, start)
|
||||
end
|
||||
prepended = vim9.slice(line, start, vim9.ops.Minus(lastword, 1))
|
||||
return vim9.fn.byteidx(line, lastword)
|
||||
end
|
||||
|
||||
-- # Return list of matches.
|
||||
|
||||
local base = prepended .. abase
|
||||
|
||||
-- # Don't do anything for an empty base, would result in all the tags in the
|
||||
-- # tags file.
|
||||
if base == '' then
|
||||
return {}
|
||||
end
|
||||
|
||||
-- # init cache for vimgrep to empty
|
||||
grepCache = {}
|
||||
|
||||
-- # Split item in words, keep empty word after "." or "->".
|
||||
-- # "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc.
|
||||
-- # We can't use split, because we need to skip nested [...].
|
||||
-- # "aa[...]" -> ['aa', '[...]'], "aa.bb[...]" -> ['aa', 'bb', '[...]'], etc.
|
||||
local items = {}
|
||||
local s = 0
|
||||
local arrays = 0
|
||||
while 1 do
|
||||
local e = vim9.fn.charidx(base, vim9.fn.match(base, '\\.\\|->\\|\\[', s))
|
||||
if e < 0 then
|
||||
if s == 0 or vim9.index(base, vim9.ops.Minus(s, 1)) ~= ']' then
|
||||
vim9.fn.add(items, vim9.slice(base, s, nil))
|
||||
end
|
||||
break
|
||||
end
|
||||
if s == 0 or vim9.index(base, vim9.ops.Minus(s, 1)) ~= ']' then
|
||||
vim9.fn.add(items, vim9.slice(base, s, vim9.ops.Minus(e, 1)))
|
||||
end
|
||||
if vim9.index(base, e) == '.' then
|
||||
-- # skip over '.'
|
||||
s = vim9.ops.Plus(e, 1)
|
||||
elseif vim9.bool(vim9.index(base, e) == '-') then
|
||||
-- # skip over '->'
|
||||
s = vim9.ops.Plus(e, 2)
|
||||
else
|
||||
-- # Skip over [...].
|
||||
local n = 0
|
||||
s = e
|
||||
e = e + 1
|
||||
while e < vim9.fn.strcharlen(base) do
|
||||
if vim9.index(base, e) == ']' then
|
||||
if n == 0 then
|
||||
break
|
||||
end
|
||||
n = n - 1
|
||||
elseif vim9.bool(vim9.index(base, e) == '[') then
|
||||
n = n + 1
|
||||
end
|
||||
e = e + 1
|
||||
end
|
||||
e = e + 1
|
||||
vim9.fn.add(items, vim9.slice(base, s, vim9.ops.Minus(e, 1)))
|
||||
arrays = arrays + 1
|
||||
s = e
|
||||
end
|
||||
end
|
||||
|
||||
-- # Find the variable items[0].
|
||||
-- # 1. in current function (like with "gd")
|
||||
-- # 2. in tags file(s) (like with ":tag")
|
||||
-- # 3. in current file (like with "gD")
|
||||
local res = {}
|
||||
if vim9.fn.searchdecl(vim9.index(items, 0), false, true) == 0 then
|
||||
-- # Found, now figure out the type.
|
||||
-- # TODO: join previous line if it makes sense
|
||||
local line = vim9.fn.getline('.')
|
||||
local col = vim9.fn.charcol('.')
|
||||
if vim9.fn.stridx(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), ';') >= 0 then
|
||||
-- # Handle multiple declarations on the same line.
|
||||
local col2 = vim9.ops.Minus(col, 1)
|
||||
while vim9.index(line, col2) ~= ';' do
|
||||
col2 = col2 - 1
|
||||
end
|
||||
line = vim9.slice(line, vim9.ops.Plus(col2, 1), nil)
|
||||
col = vim9.ops.Minus(col, col2)
|
||||
end
|
||||
if vim9.fn.stridx(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), ',') >= 0 then
|
||||
-- # Handle multiple declarations on the same line in a function
|
||||
-- # declaration.
|
||||
local col2 = vim9.ops.Minus(col, 1)
|
||||
while vim9.index(line, col2) ~= ',' do
|
||||
col2 = col2 - 1
|
||||
end
|
||||
if
|
||||
vim9.ops.RegexpMatches(
|
||||
vim9.slice(line, vim9.ops.Plus(col2, 1), vim9.ops.Minus(col, 1)),
|
||||
' *[^ ][^ ]* *[^ ]'
|
||||
)
|
||||
then
|
||||
line = vim9.slice(line, vim9.ops.Plus(col2, 1), nil)
|
||||
col = vim9.ops.Minus(col, col2)
|
||||
end
|
||||
end
|
||||
if vim9.fn.len(items) == 1 then
|
||||
-- # Completing one word and it's a local variable: May add '[', '.' or
|
||||
-- # '->'.
|
||||
local match = vim9.index(items, 0)
|
||||
local kind = 'v'
|
||||
if vim9.fn.match(line, '\\<' .. match .. '\\s*\\[') > 0 then
|
||||
match = match .. '['
|
||||
else
|
||||
res = Nextitem(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), { '' }, 0, true)
|
||||
if vim9.fn.len(res) > 0 then
|
||||
-- # There are members, thus add "." or "->".
|
||||
if vim9.fn.match(line, '\\*[ \\t(]*' .. match .. '\\>') > 0 then
|
||||
match = match .. '->'
|
||||
else
|
||||
match = match .. '.'
|
||||
end
|
||||
end
|
||||
end
|
||||
res = { { ['match'] = match, ['tagline'] = '', ['kind'] = kind, ['info'] = line } }
|
||||
elseif vim9.bool(vim9.fn.len(items) == vim9.ops.Plus(arrays, 1)) then
|
||||
-- # Completing one word and it's a local array variable: build tagline
|
||||
-- # from declaration line
|
||||
local match = vim9.index(items, 0)
|
||||
local kind = 'v'
|
||||
local tagline = '\t/^' .. line .. '$/'
|
||||
res = { { ['match'] = match, ['tagline'] = tagline, ['kind'] = kind, ['info'] = line } }
|
||||
else
|
||||
-- # Completing "var.", "var.something", etc.
|
||||
res =
|
||||
Nextitem(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), vim9.slice(items, 1, nil), 0, true)
|
||||
end
|
||||
end
|
||||
|
||||
if vim9.fn.len(items) == 1 or vim9.fn.len(items) == vim9.ops.Plus(arrays, 1) then
|
||||
-- # Only one part, no "." or "->": complete from tags file.
|
||||
local tags = {}
|
||||
if vim9.fn.len(items) == 1 then
|
||||
tags = vim9.fn.taglist('^' .. base)
|
||||
else
|
||||
tags = vim9.fn.taglist('^' .. vim9.index(items, 0) .. '$')
|
||||
end
|
||||
|
||||
vim9.fn_mut('filter', {
|
||||
vim9.fn_mut('filter', {
|
||||
tags,
|
||||
function(_, v)
|
||||
return vim9.ternary(vim9.fn.has_key(v, 'kind'), function()
|
||||
return v.kind ~= 'm'
|
||||
end, true)
|
||||
end,
|
||||
}, { replace = 0 }),
|
||||
function(_, v)
|
||||
return vim9.ops.Or(
|
||||
vim9.ops.Or(
|
||||
vim9.prefix['Bang'](vim9.fn.has_key(v, 'static')),
|
||||
vim9.prefix['Bang'](vim9.index(v, 'static'))
|
||||
),
|
||||
vim9.fn.bufnr('%') == vim9.fn.bufnr(vim9.index(v, 'filename'))
|
||||
)
|
||||
end,
|
||||
}, { replace = 0 })
|
||||
|
||||
res = vim9.fn.extend(
|
||||
res,
|
||||
vim9.fn.map(tags, function(_, v)
|
||||
return Tag2item(v)
|
||||
end)
|
||||
)
|
||||
end
|
||||
|
||||
if vim9.fn.len(res) == 0 then
|
||||
-- # Find the variable in the tags file(s)
|
||||
local diclist = vim9.fn.filter(
|
||||
vim9.fn.taglist('^' .. vim9.index(items, 0) .. '$'),
|
||||
function(_, v)
|
||||
return vim9.ternary(vim9.fn.has_key(v, 'kind'), function()
|
||||
return v.kind ~= 'm'
|
||||
end, true)
|
||||
end
|
||||
)
|
||||
|
||||
res = {}
|
||||
|
||||
for _, i in vim9.iter(vim9.fn.range(vim9.fn.len(diclist))) do
|
||||
-- # New ctags has the "typeref" field. Patched version has "typename".
|
||||
if vim9.bool(vim9.fn.has_key(vim9.index(diclist, i), 'typename')) then
|
||||
res = vim9.fn.extend(
|
||||
res,
|
||||
StructMembers(
|
||||
vim9.index(vim9.index(diclist, i), 'typename'),
|
||||
vim9.slice(items, 1, nil),
|
||||
true
|
||||
)
|
||||
)
|
||||
elseif vim9.bool(vim9.fn.has_key(vim9.index(diclist, i), 'typeref')) then
|
||||
res = vim9.fn.extend(
|
||||
res,
|
||||
StructMembers(
|
||||
vim9.index(vim9.index(diclist, i), 'typeref'),
|
||||
vim9.slice(items, 1, nil),
|
||||
true
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
-- # For a variable use the command, which must be a search pattern that
|
||||
-- # shows the declaration of the variable.
|
||||
if vim9.index(vim9.index(diclist, i), 'kind') == 'v' then
|
||||
local line = vim9.index(vim9.index(diclist, i), 'cmd')
|
||||
if vim9.slice(line, nil, 1) == '/^' then
|
||||
local col =
|
||||
vim9.fn.charidx(line, vim9.fn.match(line, '\\<' .. vim9.index(items, 0) .. '\\>'))
|
||||
res = vim9.fn.extend(
|
||||
res,
|
||||
Nextitem(
|
||||
vim9.slice(line, 2, vim9.ops.Minus(col, 1)),
|
||||
vim9.slice(items, 1, nil),
|
||||
0,
|
||||
true
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if vim9.fn.len(res) == 0 and vim9.fn.searchdecl(vim9.index(items, 0), true) == 0 then
|
||||
-- # Found, now figure out the type.
|
||||
-- # TODO: join previous line if it makes sense
|
||||
local line = vim9.fn.getline('.')
|
||||
local col = vim9.fn.charcol('.')
|
||||
res =
|
||||
Nextitem(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), vim9.slice(items, 1, nil), 0, true)
|
||||
end
|
||||
|
||||
-- # If the last item(s) are [...] they need to be added to the matches.
|
||||
local last = vim9.fn.len(items) - 1
|
||||
local brackets = ''
|
||||
while last >= 0 do
|
||||
if vim9.index(vim9.index(items, last), 0) ~= '[' then
|
||||
break
|
||||
end
|
||||
brackets = vim9.index(items, last) .. brackets
|
||||
last = last - 1
|
||||
end
|
||||
|
||||
return vim9.fn.map(res, function(_, v)
|
||||
return Tagline2item(v, brackets)
|
||||
end)
|
||||
end
|
||||
M['Complete'] = Complete
|
||||
|
||||
GetAddition = function(line, match, memarg, bracket)
|
||||
bracket = vim9.bool(bracket)
|
||||
-- # Guess if the item is an array.
|
||||
if vim9.bool(vim9.ops.And(bracket, vim9.fn.match(line, match .. '\\s*\\[') > 0)) then
|
||||
return '['
|
||||
end
|
||||
|
||||
-- # Check if the item has members.
|
||||
if vim9.fn.len(SearchMembers(memarg, { '' }, false)) > 0 then
|
||||
-- # If there is a '*' before the name use "->".
|
||||
if vim9.fn.match(line, '\\*[ \\t(]*' .. match .. '\\>') > 0 then
|
||||
return '->'
|
||||
else
|
||||
return '.'
|
||||
end
|
||||
end
|
||||
return ''
|
||||
end
|
||||
|
||||
Tag2item = function(val)
|
||||
-- # Turn the tag info "val" into an item for completion.
|
||||
-- # "val" is is an item in the list returned by taglist().
|
||||
-- # If it is a variable we may add "." or "->". Don't do it for other types,
|
||||
-- # such as a typedef, by not including the info that GetAddition() uses.
|
||||
local res = vim9.convert.decl_dict({ ['match'] = vim9.index(val, 'name') })
|
||||
|
||||
res[vim9.index_expr('extra')] =
|
||||
Tagcmd2extra(vim9.index(val, 'cmd'), vim9.index(val, 'name'), vim9.index(val, 'filename'))
|
||||
|
||||
local s = Dict2info(val)
|
||||
if s ~= '' then
|
||||
res[vim9.index_expr('info')] = s
|
||||
end
|
||||
|
||||
res[vim9.index_expr('tagline')] = ''
|
||||
if vim9.bool(vim9.fn.has_key(val, 'kind')) then
|
||||
local kind = vim9.index(val, 'kind')
|
||||
res[vim9.index_expr('kind')] = kind
|
||||
if kind == 'v' then
|
||||
res[vim9.index_expr('tagline')] = '\t' .. vim9.index(val, 'cmd')
|
||||
res[vim9.index_expr('dict')] = val
|
||||
elseif vim9.bool(kind == 'f') then
|
||||
res[vim9.index_expr('match')] = vim9.index(val, 'name') .. '('
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
Dict2info = function(dict)
|
||||
-- # Use all the items in dictionary for the "info" entry.
|
||||
local info = ''
|
||||
|
||||
for _, k in vim9.iter(vim9.fn_mut('sort', { vim9.fn.keys(dict) }, { replace = 0 })) do
|
||||
info = info .. k .. vim9.fn['repeat'](' ', 10 - vim9.fn.strlen(k))
|
||||
if k == 'cmd' then
|
||||
info = info
|
||||
.. vim9.fn.substitute(
|
||||
vim9.fn.matchstr(vim9.index(dict, 'cmd'), '/^\\s*\\zs.*\\ze$/'),
|
||||
'\\\\\\(.\\)',
|
||||
'\\1',
|
||||
'g'
|
||||
)
|
||||
else
|
||||
local dictk = vim9.index(dict, k)
|
||||
if vim9.fn.typename(dictk) ~= 'string' then
|
||||
info = info .. vim9.fn.string(dictk)
|
||||
else
|
||||
info = info .. dictk
|
||||
end
|
||||
end
|
||||
info = info .. '\n'
|
||||
end
|
||||
|
||||
return info
|
||||
end
|
||||
|
||||
ParseTagline = function(line)
|
||||
-- # Parse a tag line and return a dictionary with items like taglist()
|
||||
local l = vim9.fn.split(line, '\t')
|
||||
local d = vim.empty_dict()
|
||||
if vim9.fn.len(l) >= 3 then
|
||||
d[vim9.index_expr('name')] = vim9.index(l, 0)
|
||||
d[vim9.index_expr('filename')] = vim9.index(l, 1)
|
||||
d[vim9.index_expr('cmd')] = vim9.index(l, 2)
|
||||
local n = 2
|
||||
if vim9.ops.RegexpMatches(vim9.index(l, 2), '^/') then
|
||||
-- # Find end of cmd, it may contain Tabs.
|
||||
while n < vim9.fn.len(l) and vim9.ops.NotRegexpMatches(vim9.index(l, n), '/;"$') do
|
||||
n = n + 1
|
||||
d[vim9.index_expr('cmd')] = vim9.index(d, 'cmd') .. ' ' .. vim9.index(l, n)
|
||||
end
|
||||
end
|
||||
|
||||
for _, i in vim9.iter(vim9.fn.range(vim9.ops.Plus(n, 1), vim9.fn.len(l) - 1)) do
|
||||
if vim9.index(l, i) == 'file:' then
|
||||
d[vim9.index_expr('static')] = 1
|
||||
elseif vim9.bool(vim9.ops.NotRegexpMatches(vim9.index(l, i), ':')) then
|
||||
d[vim9.index_expr('kind')] = vim9.index(l, i)
|
||||
else
|
||||
d[vim9.index_expr(vim9.fn.matchstr(vim9.index(l, i), '[^:]*'))] =
|
||||
vim9.fn.matchstr(vim9.index(l, i), ':\\zs.*')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return d
|
||||
end
|
||||
|
||||
Tagline2item = function(val, brackets)
|
||||
-- # Turn a match item "val" into an item for completion.
|
||||
-- # "val['match']" is the matching item.
|
||||
-- # "val['tagline']" is the tagline in which the last part was found.
|
||||
local line = vim9.index(val, 'tagline')
|
||||
local add = GetAddition(line, vim9.index(val, 'match'), { val }, brackets == '')
|
||||
local res = vim9.convert.decl_dict({ ['word'] = vim9.index(val, 'match') .. brackets .. add })
|
||||
|
||||
if vim9.bool(vim9.fn.has_key(val, 'info')) then
|
||||
-- # Use info from Tag2item().
|
||||
res[vim9.index_expr('info')] = vim9.index(val, 'info')
|
||||
else
|
||||
-- # Parse the tag line and add each part to the "info" entry.
|
||||
local s = Dict2info(ParseTagline(line))
|
||||
if s ~= '' then
|
||||
res[vim9.index_expr('info')] = s
|
||||
end
|
||||
end
|
||||
|
||||
if vim9.bool(vim9.fn.has_key(val, 'kind')) then
|
||||
res[vim9.index_expr('kind')] = vim9.index(val, 'kind')
|
||||
elseif vim9.bool(add == '(') then
|
||||
res[vim9.index_expr('kind')] = 'f'
|
||||
else
|
||||
local s = vim9.fn.matchstr(line, '\\t\\(kind:\\)\\=\\zs\\S\\ze\\(\\t\\|$\\)')
|
||||
if s ~= '' then
|
||||
res[vim9.index_expr('kind')] = s
|
||||
end
|
||||
end
|
||||
|
||||
if vim9.bool(vim9.fn.has_key(val, 'extra')) then
|
||||
res[vim9.index_expr('menu')] = vim9.index(val, 'extra')
|
||||
return res
|
||||
end
|
||||
|
||||
-- # Isolate the command after the tag and filename.
|
||||
local s = vim9.fn.matchstr(
|
||||
line,
|
||||
'[^\\t]*\\t[^\\t]*\\t\\zs\\(/^.*$/\\|[^\\t]*\\)\\ze\\(;"\\t\\|\\t\\|$\\)'
|
||||
)
|
||||
if s ~= '' then
|
||||
res[vim9.index_expr('menu')] = Tagcmd2extra(
|
||||
s,
|
||||
vim9.index(val, 'match'),
|
||||
vim9.fn.matchstr(line, '[^\\t]*\\t\\zs[^\\t]*\\ze\\t')
|
||||
)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
Tagcmd2extra = function(cmd, name, fname)
|
||||
-- # Turn a command from a tag line to something that is useful in the menu
|
||||
local x = ''
|
||||
if vim9.ops.RegexpMatches(cmd, '^/^') then
|
||||
-- # The command is a search command, useful to see what it is.
|
||||
x = vim9.fn.substitute(
|
||||
vim9.fn.substitute(
|
||||
vim9.fn.matchstr(cmd, '^/^\\s*\\zs.*\\ze$/'),
|
||||
'\\<' .. name .. '\\>',
|
||||
'@@',
|
||||
''
|
||||
),
|
||||
'\\\\\\(.\\)',
|
||||
'\\1',
|
||||
'g'
|
||||
) .. ' - ' .. fname
|
||||
elseif vim9.bool(vim9.ops.RegexpMatches(cmd, '^\\d*$')) then
|
||||
-- # The command is a line number, the file name is more useful.
|
||||
x = fname .. ' - ' .. cmd
|
||||
else
|
||||
-- # Not recognized, use command and file name.
|
||||
x = cmd .. ' - ' .. fname
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
Nextitem = function(lead, items, depth, all)
|
||||
all = vim9.bool(all)
|
||||
-- # Find composing type in "lead" and match items[0] with it.
|
||||
-- # Repeat this recursively for items[1], if it's there.
|
||||
-- # When resolving typedefs "depth" is used to avoid infinite recursion.
|
||||
-- # Return the list of matches.
|
||||
|
||||
-- # Use the text up to the variable name and split it in tokens.
|
||||
local tokens = vim9.fn.split(lead, '\\s\\+\\|\\<')
|
||||
|
||||
-- # Try to recognize the type of the variable. This is rough guessing...
|
||||
local res = {}
|
||||
|
||||
local body = function(_, tidx)
|
||||
-- # Skip tokens starting with a non-ID character.
|
||||
if vim9.ops.NotRegexpMatches(vim9.index(tokens, tidx), '^\\h') then
|
||||
return vim9.ITER_CONTINUE
|
||||
end
|
||||
|
||||
-- # Recognize "struct foobar" and "union foobar".
|
||||
-- # Also do "class foobar" when it's C++ after all (doesn't work very well
|
||||
-- # though).
|
||||
if
|
||||
(
|
||||
vim9.index(tokens, tidx) == 'struct'
|
||||
or vim9.index(tokens, tidx) == 'union'
|
||||
or vim9.index(tokens, tidx) == 'class'
|
||||
) and vim9.ops.Plus(tidx, 1) < vim9.fn.len(tokens)
|
||||
then
|
||||
res = StructMembers(
|
||||
vim9.index(tokens, tidx) .. ':' .. vim9.index(tokens, vim9.ops.Plus(tidx, 1)),
|
||||
items,
|
||||
all
|
||||
)
|
||||
return vim9.ITER_BREAK
|
||||
end
|
||||
|
||||
-- # TODO: add more reserved words
|
||||
if
|
||||
vim9.fn.index(
|
||||
{ 'int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern' },
|
||||
vim9.index(tokens, tidx)
|
||||
) >= 0
|
||||
then
|
||||
return vim9.ITER_CONTINUE
|
||||
end
|
||||
|
||||
-- # Use the tags file to find out if this is a typedef.
|
||||
local diclist = vim9.fn.taglist('^' .. vim9.index(tokens, tidx) .. '$')
|
||||
|
||||
local body = function(_, tagidx)
|
||||
local item = vim9.convert.decl_dict(vim9.index(diclist, tagidx))
|
||||
|
||||
-- # New ctags has the "typeref" field. Patched version has "typename".
|
||||
if vim9.bool(vim9.fn.has_key(item, 'typeref')) then
|
||||
res = vim9.fn.extend(res, StructMembers(vim9.index(item, 'typeref'), items, all))
|
||||
return vim9.ITER_CONTINUE
|
||||
end
|
||||
if vim9.bool(vim9.fn.has_key(item, 'typename')) then
|
||||
res = vim9.fn.extend(res, StructMembers(vim9.index(item, 'typename'), items, all))
|
||||
return vim9.ITER_CONTINUE
|
||||
end
|
||||
|
||||
-- # Only handle typedefs here.
|
||||
if vim9.index(item, 'kind') ~= 't' then
|
||||
return vim9.ITER_CONTINUE
|
||||
end
|
||||
|
||||
-- # Skip matches local to another file.
|
||||
if
|
||||
vim9.bool(
|
||||
vim9.ops.And(
|
||||
vim9.ops.And(vim9.fn.has_key(item, 'static'), vim9.index(item, 'static')),
|
||||
vim9.fn.bufnr('%') ~= vim9.fn.bufnr(vim9.index(item, 'filename'))
|
||||
)
|
||||
)
|
||||
then
|
||||
return vim9.ITER_CONTINUE
|
||||
end
|
||||
|
||||
-- # For old ctags we recognize "typedef struct aaa" and
|
||||
-- # "typedef union bbb" in the tags file command.
|
||||
local cmd = vim9.index(item, 'cmd')
|
||||
local ei = vim9.fn.charidx(cmd, vim9.fn.matchend(cmd, 'typedef\\s\\+'))
|
||||
if ei > 1 then
|
||||
local cmdtokens = vim9.fn.split(vim9.slice(cmd, ei, nil), '\\s\\+\\|\\<')
|
||||
if vim9.fn.len(cmdtokens) > 1 then
|
||||
if
|
||||
vim9.index(cmdtokens, 0) == 'struct'
|
||||
or vim9.index(cmdtokens, 0) == 'union'
|
||||
or vim9.index(cmdtokens, 0) == 'class'
|
||||
then
|
||||
local name = ''
|
||||
-- # Use the first identifier after the "struct" or "union"
|
||||
|
||||
for _, ti in vim9.iter(vim9.fn.range((vim9.fn.len(cmdtokens) - 1))) do
|
||||
if vim9.ops.RegexpMatches(vim9.index(cmdtokens, ti), '^\\w') then
|
||||
name = vim9.index(cmdtokens, ti)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if name ~= '' then
|
||||
res = vim9.fn.extend(
|
||||
res,
|
||||
StructMembers(vim9.index(cmdtokens, 0) .. ':' .. name, items, all)
|
||||
)
|
||||
end
|
||||
elseif vim9.bool(depth < 10) then
|
||||
-- # Could be "typedef other_T some_T".
|
||||
res = vim9.fn.extend(
|
||||
res,
|
||||
Nextitem(vim9.index(cmdtokens, 0), items, vim9.ops.Plus(depth, 1), all)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return vim9.ITER_DEFAULT
|
||||
end
|
||||
|
||||
for _, tagidx in vim9.iter(vim9.fn.range(vim9.fn.len(diclist))) do
|
||||
local nvim9_status, nvim9_ret = body(_, tagidx)
|
||||
if nvim9_status == vim9.ITER_BREAK then
|
||||
break
|
||||
elseif nvim9_status == vim9.ITER_RETURN then
|
||||
return nvim9_ret
|
||||
end
|
||||
end
|
||||
|
||||
if vim9.fn.len(res) > 0 then
|
||||
return vim9.ITER_BREAK
|
||||
end
|
||||
|
||||
return vim9.ITER_DEFAULT
|
||||
end
|
||||
|
||||
for _, tidx in vim9.iter(vim9.fn.range(vim9.fn.len(tokens))) do
|
||||
local nvim9_status, nvim9_ret = body(_, tidx)
|
||||
if nvim9_status == vim9.ITER_BREAK then
|
||||
break
|
||||
elseif nvim9_status == vim9.ITER_RETURN then
|
||||
return nvim9_ret
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
StructMembers = function(atypename, items, all)
|
||||
all = vim9.bool(all)
|
||||
|
||||
-- # Search for members of structure "typename" in tags files.
|
||||
-- # Return a list with resulting matches.
|
||||
-- # Each match is a dictionary with "match" and "tagline" entries.
|
||||
-- # When "all" is true find all, otherwise just return 1 if there is any member.
|
||||
|
||||
-- # Todo: What about local structures?
|
||||
local fnames = vim9.fn.join(vim9.fn.map(vim9.fn.tagfiles(), function(_, v)
|
||||
return vim9.fn.escape(v, ' \\#%')
|
||||
end))
|
||||
if fnames == '' then
|
||||
return {}
|
||||
end
|
||||
|
||||
local typename = atypename
|
||||
local qflist = {}
|
||||
local cached = 0
|
||||
local n = ''
|
||||
if vim9.bool(vim9.prefix['Bang'](all)) then
|
||||
n = '1'
|
||||
if vim9.bool(vim9.fn.has_key(grepCache, typename)) then
|
||||
qflist = vim9.index(grepCache, typename)
|
||||
cached = 1
|
||||
end
|
||||
else
|
||||
n = ''
|
||||
end
|
||||
if vim9.bool(vim9.prefix['Bang'](cached)) then
|
||||
while 1 do
|
||||
vim.api.nvim_command(
|
||||
'silent! keepjumps noautocmd '
|
||||
.. n
|
||||
.. 'vimgrep '
|
||||
.. '/\\t'
|
||||
.. typename
|
||||
.. '\\(\\t\\|$\\)/j '
|
||||
.. fnames
|
||||
)
|
||||
|
||||
qflist = vim9.fn.getqflist()
|
||||
if vim9.fn.len(qflist) > 0 or vim9.fn.match(typename, '::') < 0 then
|
||||
break
|
||||
end
|
||||
-- # No match for "struct:context::name", remove "context::" and try again.
|
||||
typename = vim9.fn.substitute(typename, ':[^:]*::', ':', '')
|
||||
end
|
||||
|
||||
if vim9.bool(vim9.prefix['Bang'](all)) then
|
||||
-- # Store the result to be able to use it again later.
|
||||
grepCache[vim9.index_expr(typename)] = qflist
|
||||
end
|
||||
end
|
||||
|
||||
-- # Skip over [...] items
|
||||
local idx = 0
|
||||
local target = ''
|
||||
while 1 do
|
||||
if idx >= vim9.fn.len(items) then
|
||||
target = ''
|
||||
break
|
||||
end
|
||||
if vim9.index(vim9.index(items, idx), 0) ~= '[' then
|
||||
target = vim9.index(items, idx)
|
||||
break
|
||||
end
|
||||
idx = idx + 1
|
||||
end
|
||||
-- # Put matching members in matches[].
|
||||
local matches = {}
|
||||
|
||||
for _, l in vim9.iter(qflist) do
|
||||
local memb = vim9.fn.matchstr(vim9.index(l, 'text'), '[^\\t]*')
|
||||
if vim9.ops.RegexpMatches(memb, '^' .. target) then
|
||||
-- # Skip matches local to another file.
|
||||
if
|
||||
vim9.fn.match(vim9.index(l, 'text'), '\tfile:') < 0
|
||||
or vim9.fn.bufnr('%')
|
||||
== vim9.fn.bufnr(vim9.fn.matchstr(vim9.index(l, 'text'), '\\t\\zs[^\\t]*'))
|
||||
then
|
||||
local item =
|
||||
vim9.convert.decl_dict({ ['match'] = memb, ['tagline'] = vim9.index(l, 'text') })
|
||||
|
||||
-- # Add the kind of item.
|
||||
local s =
|
||||
vim9.fn.matchstr(vim9.index(l, 'text'), '\\t\\(kind:\\)\\=\\zs\\S\\ze\\(\\t\\|$\\)')
|
||||
if s ~= '' then
|
||||
item[vim9.index_expr('kind')] = s
|
||||
if s == 'f' then
|
||||
item[vim9.index_expr('match')] = memb .. '('
|
||||
end
|
||||
end
|
||||
|
||||
vim9.fn.add(matches, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if vim9.fn.len(matches) > 0 then
|
||||
-- # Skip over next [...] items
|
||||
idx = idx + 1
|
||||
while 1 do
|
||||
if idx >= vim9.fn.len(items) then
|
||||
return matches
|
||||
end
|
||||
if vim9.index(vim9.index(items, idx), 0) ~= '[' then
|
||||
break
|
||||
end
|
||||
idx = idx + 1
|
||||
end
|
||||
|
||||
-- # More items following. For each of the possible members find the
|
||||
-- # matching following members.
|
||||
return SearchMembers(matches, vim9.slice(items, idx, nil), all)
|
||||
end
|
||||
|
||||
-- # Failed to find anything.
|
||||
return {}
|
||||
end
|
||||
|
||||
SearchMembers = function(matches, items, all)
|
||||
all = vim9.bool(all)
|
||||
|
||||
-- # For matching members, find matches for following items.
|
||||
-- # When "all" is true find all, otherwise just return 1 if there is any member.
|
||||
local res = {}
|
||||
|
||||
for _, i in vim9.iter(vim9.fn.range(vim9.fn.len(matches))) do
|
||||
local typename = ''
|
||||
local line = ''
|
||||
if vim9.bool(vim9.fn.has_key(vim9.index(matches, i), 'dict')) then
|
||||
if vim9.bool(vim9.fn.has_key(vim9.index(vim9.index(matches, i), 'dict'), 'typename')) then
|
||||
typename = vim9.index(vim9.index(vim9.index(matches, i), 'dict'), 'typename')
|
||||
elseif vim9.bool(vim9.fn.has_key(vim9.index(vim9.index(matches, i), 'dict'), 'typeref')) then
|
||||
typename = vim9.index(vim9.index(vim9.index(matches, i), 'dict'), 'typeref')
|
||||
end
|
||||
line = '\t' .. vim9.index(vim9.index(vim9.index(matches, i), 'dict'), 'cmd')
|
||||
else
|
||||
line = vim9.index(vim9.index(matches, i), 'tagline')
|
||||
local eb = vim9.fn.matchend(line, '\\ttypename:')
|
||||
local e = vim9.fn.charidx(line, eb)
|
||||
if e < 0 then
|
||||
eb = vim9.fn.matchend(line, '\\ttyperef:')
|
||||
e = vim9.fn.charidx(line, eb)
|
||||
end
|
||||
if e > 0 then
|
||||
-- # Use typename field
|
||||
typename = vim9.fn.matchstr(line, '[^\\t]*', eb)
|
||||
end
|
||||
end
|
||||
|
||||
if typename ~= '' then
|
||||
res = vim9.fn.extend(res, StructMembers(typename, items, all))
|
||||
else
|
||||
-- # Use the search command (the declaration itself).
|
||||
local sb = vim9.fn.match(line, '\\t\\zs/^')
|
||||
local s = vim9.fn.charidx(line, sb)
|
||||
if s > 0 then
|
||||
local e = vim9.fn.charidx(
|
||||
line,
|
||||
vim9.fn.match(line, '\\<' .. vim9.index(vim9.index(matches, i), 'match') .. '\\>', sb)
|
||||
)
|
||||
if e > 0 then
|
||||
res =
|
||||
vim9.fn.extend(res, Nextitem(vim9.slice(line, s, vim9.ops.Minus(e, 1)), items, 0, all))
|
||||
end
|
||||
end
|
||||
end
|
||||
if vim9.bool(vim9.ops.And(vim9.prefix['Bang'](all), vim9.fn.len(res) > 0)) then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- #}}}1
|
||||
|
||||
-- # vim: noet sw=2 sts=2
|
||||
return M
|
@@ -1,8 +1,682 @@
|
||||
" Generated vim file by vim9jit. Please do not edit
|
||||
let s:path = expand("<script>")
|
||||
let s:lua_path = fnamemodify(s:path, ":r") . ".lua"
|
||||
let s:nvim_module = luaeval('require("_vim9script").autoload(_A)', s:lua_path)
|
||||
" Vim completion script
|
||||
" Language: C
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2020 Nov 14
|
||||
|
||||
function! ccomplete#Complete(findstart, abase) abort
|
||||
return s:nvim_module.Complete(a:findstart, a:abase)
|
||||
endfunction
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" This function is used for the 'omnifunc' option.
|
||||
func ccomplete#Complete(findstart, base)
|
||||
if a:findstart
|
||||
" Locate the start of the item, including ".", "->" and "[...]".
|
||||
let line = getline('.')
|
||||
let start = col('.') - 1
|
||||
let lastword = -1
|
||||
while start > 0
|
||||
if line[start - 1] =~ '\w'
|
||||
let start -= 1
|
||||
elseif line[start - 1] =~ '\.'
|
||||
if lastword == -1
|
||||
let lastword = start
|
||||
endif
|
||||
let start -= 1
|
||||
elseif start > 1 && line[start - 2] == '-' && line[start - 1] == '>'
|
||||
if lastword == -1
|
||||
let lastword = start
|
||||
endif
|
||||
let start -= 2
|
||||
elseif line[start - 1] == ']'
|
||||
" Skip over [...].
|
||||
let n = 0
|
||||
let start -= 1
|
||||
while start > 0
|
||||
let start -= 1
|
||||
if line[start] == '['
|
||||
if n == 0
|
||||
break
|
||||
endif
|
||||
let n -= 1
|
||||
elseif line[start] == ']' " nested []
|
||||
let n += 1
|
||||
endif
|
||||
endwhile
|
||||
else
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
" Return the column of the last word, which is going to be changed.
|
||||
" Remember the text that comes before it in s:prepended.
|
||||
if lastword == -1
|
||||
let s:prepended = ''
|
||||
return start
|
||||
endif
|
||||
let s:prepended = strpart(line, start, lastword - start)
|
||||
return lastword
|
||||
endif
|
||||
|
||||
" Return list of matches.
|
||||
|
||||
let base = s:prepended . a:base
|
||||
|
||||
" Don't do anything for an empty base, would result in all the tags in the
|
||||
" tags file.
|
||||
if base == ''
|
||||
return []
|
||||
endif
|
||||
|
||||
" init cache for vimgrep to empty
|
||||
let s:grepCache = {}
|
||||
|
||||
" Split item in words, keep empty word after "." or "->".
|
||||
" "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc.
|
||||
" We can't use split, because we need to skip nested [...].
|
||||
" "aa[...]" -> ['aa', '[...]'], "aa.bb[...]" -> ['aa', 'bb', '[...]'], etc.
|
||||
let items = []
|
||||
let s = 0
|
||||
let arrays = 0
|
||||
while 1
|
||||
let e = match(base, '\.\|->\|\[', s)
|
||||
if e < 0
|
||||
if s == 0 || base[s - 1] != ']'
|
||||
call add(items, strpart(base, s))
|
||||
endif
|
||||
break
|
||||
endif
|
||||
if s == 0 || base[s - 1] != ']'
|
||||
call add(items, strpart(base, s, e - s))
|
||||
endif
|
||||
if base[e] == '.'
|
||||
let s = e + 1 " skip over '.'
|
||||
elseif base[e] == '-'
|
||||
let s = e + 2 " skip over '->'
|
||||
else
|
||||
" Skip over [...].
|
||||
let n = 0
|
||||
let s = e
|
||||
let e += 1
|
||||
while e < len(base)
|
||||
if base[e] == ']'
|
||||
if n == 0
|
||||
break
|
||||
endif
|
||||
let n -= 1
|
||||
elseif base[e] == '[' " nested [...]
|
||||
let n += 1
|
||||
endif
|
||||
let e += 1
|
||||
endwhile
|
||||
let e += 1
|
||||
call add(items, strpart(base, s, e - s))
|
||||
let arrays += 1
|
||||
let s = e
|
||||
endif
|
||||
endwhile
|
||||
|
||||
if complete_check()
|
||||
" return v:none
|
||||
return []
|
||||
endif
|
||||
|
||||
" Find the variable items[0].
|
||||
" 1. in current function (like with "gd")
|
||||
" 2. in tags file(s) (like with ":tag")
|
||||
" 3. in current file (like with "gD")
|
||||
let res = []
|
||||
if searchdecl(items[0], 0, 1) == 0
|
||||
" Found, now figure out the type.
|
||||
" TODO: join previous line if it makes sense
|
||||
let line = getline('.')
|
||||
let col = col('.')
|
||||
if stridx(strpart(line, 0, col), ';') != -1
|
||||
" Handle multiple declarations on the same line.
|
||||
let col2 = col - 1
|
||||
while line[col2] != ';'
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
let col2 -= 1
|
||||
endwhile
|
||||
let line = strpart(line, col2 + 1)
|
||||
let col -= col2
|
||||
endif
|
||||
if stridx(strpart(line, 0, col), ',') != -1
|
||||
" Handle multiple declarations on the same line in a function
|
||||
" declaration.
|
||||
let col2 = col - 1
|
||||
while line[col2] != ','
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
let col2 -= 1
|
||||
endwhile
|
||||
if strpart(line, col2 + 1, col - col2 - 1) =~ ' *[^ ][^ ]* *[^ ]'
|
||||
let line = strpart(line, col2 + 1)
|
||||
let col -= col2
|
||||
endif
|
||||
endif
|
||||
if len(items) == 1
|
||||
" Completing one word and it's a local variable: May add '[', '.' or
|
||||
" '->'.
|
||||
let match = items[0]
|
||||
let kind = 'v'
|
||||
if match(line, '\<' . match . '\s*\[') > 0
|
||||
let match .= '['
|
||||
else
|
||||
let res = s:Nextitem(strpart(line, 0, col), [''], 0, 1)
|
||||
if len(res) > 0
|
||||
" There are members, thus add "." or "->".
|
||||
if match(line, '\*[ \t(]*' . match . '\>') > 0
|
||||
let match .= '->'
|
||||
else
|
||||
let match .= '.'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
let res = [{'match': match, 'tagline' : '', 'kind' : kind, 'info' : line}]
|
||||
elseif len(items) == arrays + 1
|
||||
" Completing one word and it's a local array variable: build tagline
|
||||
" from declaration line
|
||||
let match = items[0]
|
||||
let kind = 'v'
|
||||
let tagline = "\t/^" . line . '$/'
|
||||
let res = [{'match': match, 'tagline' : tagline, 'kind' : kind, 'info' : line}]
|
||||
else
|
||||
" Completing "var.", "var.something", etc.
|
||||
let res = s:Nextitem(strpart(line, 0, col), items[1:], 0, 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
if len(items) == 1 || len(items) == arrays + 1
|
||||
" Only one part, no "." or "->": complete from tags file.
|
||||
if len(items) == 1
|
||||
let tags = taglist('^' . base)
|
||||
else
|
||||
let tags = taglist('^' . items[0] . '$')
|
||||
endif
|
||||
|
||||
" Remove members, these can't appear without something in front.
|
||||
call filter(tags, 'has_key(v:val, "kind") ? v:val["kind"] != "m" : 1')
|
||||
|
||||
" Remove static matches in other files.
|
||||
call filter(tags, '!has_key(v:val, "static") || !v:val["static"] || bufnr("%") == bufnr(v:val["filename"])')
|
||||
|
||||
call extend(res, map(tags, 's:Tag2item(v:val)'))
|
||||
endif
|
||||
|
||||
if len(res) == 0
|
||||
" Find the variable in the tags file(s)
|
||||
let diclist = taglist('^' . items[0] . '$')
|
||||
|
||||
" Remove members, these can't appear without something in front.
|
||||
call filter(diclist, 'has_key(v:val, "kind") ? v:val["kind"] != "m" : 1')
|
||||
|
||||
let res = []
|
||||
for i in range(len(diclist))
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
" New ctags has the "typeref" field. Patched version has "typename".
|
||||
if has_key(diclist[i], 'typename')
|
||||
call extend(res, s:StructMembers(diclist[i]['typename'], items[1:], 1))
|
||||
elseif has_key(diclist[i], 'typeref')
|
||||
call extend(res, s:StructMembers(diclist[i]['typeref'], items[1:], 1))
|
||||
endif
|
||||
|
||||
" For a variable use the command, which must be a search pattern that
|
||||
" shows the declaration of the variable.
|
||||
if diclist[i]['kind'] == 'v'
|
||||
let line = diclist[i]['cmd']
|
||||
if line[0] == '/' && line[1] == '^'
|
||||
let col = match(line, '\<' . items[0] . '\>')
|
||||
call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:], 0, 1))
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if len(res) == 0 && searchdecl(items[0], 1) == 0
|
||||
" Found, now figure out the type.
|
||||
" TODO: join previous line if it makes sense
|
||||
let line = getline('.')
|
||||
let col = col('.')
|
||||
let res = s:Nextitem(strpart(line, 0, col), items[1:], 0, 1)
|
||||
endif
|
||||
|
||||
" If the last item(s) are [...] they need to be added to the matches.
|
||||
let last = len(items) - 1
|
||||
let brackets = ''
|
||||
while last >= 0
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
if items[last][0] != '['
|
||||
break
|
||||
endif
|
||||
let brackets = items[last] . brackets
|
||||
let last -= 1
|
||||
endwhile
|
||||
|
||||
return map(res, 's:Tagline2item(v:val, brackets)')
|
||||
endfunc
|
||||
|
||||
func s:GetAddition(line, match, memarg, bracket)
|
||||
" Guess if the item is an array.
|
||||
if a:bracket && match(a:line, a:match . '\s*\[') > 0
|
||||
return '['
|
||||
endif
|
||||
|
||||
" Check if the item has members.
|
||||
if len(s:SearchMembers(a:memarg, [''], 0)) > 0
|
||||
" If there is a '*' before the name use "->".
|
||||
if match(a:line, '\*[ \t(]*' . a:match . '\>') > 0
|
||||
return '->'
|
||||
else
|
||||
return '.'
|
||||
endif
|
||||
endif
|
||||
return ''
|
||||
endfunc
|
||||
|
||||
" Turn the tag info "val" into an item for completion.
|
||||
" "val" is is an item in the list returned by taglist().
|
||||
" If it is a variable we may add "." or "->". Don't do it for other types,
|
||||
" such as a typedef, by not including the info that s:GetAddition() uses.
|
||||
func s:Tag2item(val)
|
||||
let res = {'match': a:val['name']}
|
||||
|
||||
let res['extra'] = s:Tagcmd2extra(a:val['cmd'], a:val['name'], a:val['filename'])
|
||||
|
||||
let s = s:Dict2info(a:val)
|
||||
if s != ''
|
||||
let res['info'] = s
|
||||
endif
|
||||
|
||||
let res['tagline'] = ''
|
||||
if has_key(a:val, "kind")
|
||||
let kind = a:val['kind']
|
||||
let res['kind'] = kind
|
||||
if kind == 'v'
|
||||
let res['tagline'] = "\t" . a:val['cmd']
|
||||
let res['dict'] = a:val
|
||||
elseif kind == 'f'
|
||||
let res['match'] = a:val['name'] . '('
|
||||
endif
|
||||
endif
|
||||
|
||||
return res
|
||||
endfunc
|
||||
|
||||
" Use all the items in dictionary for the "info" entry.
|
||||
func s:Dict2info(dict)
|
||||
let info = ''
|
||||
for k in sort(keys(a:dict))
|
||||
if complete_check()
|
||||
return info
|
||||
endif
|
||||
let info .= k . repeat(' ', 10 - len(k))
|
||||
if k == 'cmd'
|
||||
let info .= substitute(matchstr(a:dict['cmd'], '/^\s*\zs.*\ze$/'), '\\\(.\)', '\1', 'g')
|
||||
else
|
||||
let info .= a:dict[k]
|
||||
endif
|
||||
let info .= "\n"
|
||||
endfor
|
||||
return info
|
||||
endfunc
|
||||
|
||||
" Parse a tag line and return a dictionary with items like taglist()
|
||||
func s:ParseTagline(line)
|
||||
let l = split(a:line, "\t")
|
||||
let d = {}
|
||||
if len(l) >= 3
|
||||
let d['name'] = l[0]
|
||||
let d['filename'] = l[1]
|
||||
let d['cmd'] = l[2]
|
||||
let n = 2
|
||||
if l[2] =~ '^/'
|
||||
" Find end of cmd, it may contain Tabs.
|
||||
while n < len(l) && l[n] !~ '/;"$'
|
||||
let n += 1
|
||||
let d['cmd'] .= " " . l[n]
|
||||
endwhile
|
||||
endif
|
||||
for i in range(n + 1, len(l) - 1)
|
||||
if complete_check()
|
||||
return d
|
||||
endif
|
||||
if l[i] == 'file:'
|
||||
let d['static'] = 1
|
||||
elseif l[i] !~ ':'
|
||||
let d['kind'] = l[i]
|
||||
else
|
||||
let d[matchstr(l[i], '[^:]*')] = matchstr(l[i], ':\zs.*')
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return d
|
||||
endfunc
|
||||
|
||||
" Turn a match item "val" into an item for completion.
|
||||
" "val['match']" is the matching item.
|
||||
" "val['tagline']" is the tagline in which the last part was found.
|
||||
func s:Tagline2item(val, brackets)
|
||||
let line = a:val['tagline']
|
||||
let add = s:GetAddition(line, a:val['match'], [a:val], a:brackets == '')
|
||||
let res = {'word': a:val['match'] . a:brackets . add }
|
||||
|
||||
if has_key(a:val, 'info')
|
||||
" Use info from Tag2item().
|
||||
let res['info'] = a:val['info']
|
||||
else
|
||||
" Parse the tag line and add each part to the "info" entry.
|
||||
let s = s:Dict2info(s:ParseTagline(line))
|
||||
if s != ''
|
||||
let res['info'] = s
|
||||
endif
|
||||
endif
|
||||
|
||||
if has_key(a:val, 'kind')
|
||||
let res['kind'] = a:val['kind']
|
||||
elseif add == '('
|
||||
let res['kind'] = 'f'
|
||||
else
|
||||
let s = matchstr(line, '\t\(kind:\)\=\zs\S\ze\(\t\|$\)')
|
||||
if s != ''
|
||||
let res['kind'] = s
|
||||
endif
|
||||
endif
|
||||
|
||||
if has_key(a:val, 'extra')
|
||||
let res['menu'] = a:val['extra']
|
||||
return res
|
||||
endif
|
||||
|
||||
" Isolate the command after the tag and filename.
|
||||
let s = matchstr(line, '[^\t]*\t[^\t]*\t\zs\(/^.*$/\|[^\t]*\)\ze\(;"\t\|\t\|$\)')
|
||||
if s != ''
|
||||
let res['menu'] = s:Tagcmd2extra(s, a:val['match'], matchstr(line, '[^\t]*\t\zs[^\t]*\ze\t'))
|
||||
endif
|
||||
return res
|
||||
endfunc
|
||||
|
||||
" Turn a command from a tag line to something that is useful in the menu
|
||||
func s:Tagcmd2extra(cmd, name, fname)
|
||||
if a:cmd =~ '^/^'
|
||||
" The command is a search command, useful to see what it is.
|
||||
let x = matchstr(a:cmd, '^/^\s*\zs.*\ze$/')
|
||||
let x = substitute(x, '\<' . a:name . '\>', '@@', '')
|
||||
let x = substitute(x, '\\\(.\)', '\1', 'g')
|
||||
let x = x . ' - ' . a:fname
|
||||
elseif a:cmd =~ '^\d*$'
|
||||
" The command is a line number, the file name is more useful.
|
||||
let x = a:fname . ' - ' . a:cmd
|
||||
else
|
||||
" Not recognized, use command and file name.
|
||||
let x = a:cmd . ' - ' . a:fname
|
||||
endif
|
||||
return x
|
||||
endfunc
|
||||
|
||||
" Find composing type in "lead" and match items[0] with it.
|
||||
" Repeat this recursively for items[1], if it's there.
|
||||
" When resolving typedefs "depth" is used to avoid infinite recursion.
|
||||
" Return the list of matches.
|
||||
func s:Nextitem(lead, items, depth, all)
|
||||
|
||||
" Use the text up to the variable name and split it in tokens.
|
||||
let tokens = split(a:lead, '\s\+\|\<')
|
||||
|
||||
" Try to recognize the type of the variable. This is rough guessing...
|
||||
let res = []
|
||||
for tidx in range(len(tokens))
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
|
||||
" Skip tokens starting with a non-ID character.
|
||||
if tokens[tidx] !~ '^\h'
|
||||
continue
|
||||
endif
|
||||
|
||||
" Recognize "struct foobar" and "union foobar".
|
||||
" Also do "class foobar" when it's C++ after all (doesn't work very well
|
||||
" though).
|
||||
if (tokens[tidx] == 'struct' || tokens[tidx] == 'union' || tokens[tidx] == 'class') && tidx + 1 < len(tokens)
|
||||
let res = s:StructMembers(tokens[tidx] . ':' . tokens[tidx + 1], a:items, a:all)
|
||||
break
|
||||
endif
|
||||
|
||||
" TODO: add more reserved words
|
||||
if index(['int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0
|
||||
continue
|
||||
endif
|
||||
|
||||
" Use the tags file to find out if this is a typedef.
|
||||
let diclist = taglist('^' . tokens[tidx] . '$')
|
||||
for tagidx in range(len(diclist))
|
||||
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
|
||||
let item = diclist[tagidx]
|
||||
|
||||
" New ctags has the "typeref" field. Patched version has "typename".
|
||||
if has_key(item, 'typeref')
|
||||
call extend(res, s:StructMembers(item['typeref'], a:items, a:all))
|
||||
continue
|
||||
endif
|
||||
if has_key(item, 'typename')
|
||||
call extend(res, s:StructMembers(item['typename'], a:items, a:all))
|
||||
continue
|
||||
endif
|
||||
|
||||
" Only handle typedefs here.
|
||||
if item['kind'] != 't'
|
||||
continue
|
||||
endif
|
||||
|
||||
" Skip matches local to another file.
|
||||
if has_key(item, 'static') && item['static'] && bufnr('%') != bufnr(item['filename'])
|
||||
continue
|
||||
endif
|
||||
|
||||
" For old ctags we recognize "typedef struct aaa" and
|
||||
" "typedef union bbb" in the tags file command.
|
||||
let cmd = item['cmd']
|
||||
let ei = matchend(cmd, 'typedef\s\+')
|
||||
if ei > 1
|
||||
let cmdtokens = split(strpart(cmd, ei), '\s\+\|\<')
|
||||
if len(cmdtokens) > 1
|
||||
if cmdtokens[0] == 'struct' || cmdtokens[0] == 'union' || cmdtokens[0] == 'class'
|
||||
let name = ''
|
||||
" Use the first identifier after the "struct" or "union"
|
||||
for ti in range(len(cmdtokens) - 1)
|
||||
if cmdtokens[ti] =~ '^\w'
|
||||
let name = cmdtokens[ti]
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if name != ''
|
||||
call extend(res, s:StructMembers(cmdtokens[0] . ':' . name, a:items, a:all))
|
||||
endif
|
||||
elseif a:depth < 10
|
||||
" Could be "typedef other_T some_T".
|
||||
call extend(res, s:Nextitem(cmdtokens[0], a:items, a:depth + 1, a:all))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
if len(res) > 0
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
return res
|
||||
endfunc
|
||||
|
||||
|
||||
" Search for members of structure "typename" in tags files.
|
||||
" Return a list with resulting matches.
|
||||
" Each match is a dictionary with "match" and "tagline" entries.
|
||||
" When "all" is non-zero find all, otherwise just return 1 if there is any
|
||||
" member.
|
||||
func s:StructMembers(typename, items, all)
|
||||
" Todo: What about local structures?
|
||||
let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
|
||||
if fnames == ''
|
||||
return []
|
||||
endif
|
||||
|
||||
let typename = a:typename
|
||||
let qflist = []
|
||||
let cached = 0
|
||||
if a:all == 0
|
||||
let n = '1' " stop at first found match
|
||||
if has_key(s:grepCache, a:typename)
|
||||
let qflist = s:grepCache[a:typename]
|
||||
let cached = 1
|
||||
endif
|
||||
else
|
||||
let n = ''
|
||||
endif
|
||||
if !cached
|
||||
while 1
|
||||
if complete_check()
|
||||
return []
|
||||
endif
|
||||
exe 'silent! keepj noautocmd ' . n . 'vimgrep /\t' . typename . '\(\t\|$\)/j ' . fnames
|
||||
|
||||
let qflist = getqflist()
|
||||
if len(qflist) > 0 || match(typename, "::") < 0
|
||||
break
|
||||
endif
|
||||
" No match for "struct:context::name", remove "context::" and try again.
|
||||
let typename = substitute(typename, ':[^:]*::', ':', '')
|
||||
endwhile
|
||||
|
||||
if a:all == 0
|
||||
" Store the result to be able to use it again later.
|
||||
let s:grepCache[a:typename] = qflist
|
||||
endif
|
||||
endif
|
||||
|
||||
" Skip over [...] items
|
||||
let idx = 0
|
||||
while 1
|
||||
if complete_check()
|
||||
return []
|
||||
endif
|
||||
if idx >= len(a:items)
|
||||
let target = '' " No further items, matching all members
|
||||
break
|
||||
endif
|
||||
if a:items[idx][0] != '['
|
||||
let target = a:items[idx]
|
||||
break
|
||||
endif
|
||||
let idx += 1
|
||||
endwhile
|
||||
" Put matching members in matches[].
|
||||
let matches = []
|
||||
for l in qflist
|
||||
let memb = matchstr(l['text'], '[^\t]*')
|
||||
if memb =~ '^' . target
|
||||
" Skip matches local to another file.
|
||||
if match(l['text'], "\tfile:") < 0 || bufnr('%') == bufnr(matchstr(l['text'], '\t\zs[^\t]*'))
|
||||
let item = {'match': memb, 'tagline': l['text']}
|
||||
|
||||
" Add the kind of item.
|
||||
let s = matchstr(l['text'], '\t\(kind:\)\=\zs\S\ze\(\t\|$\)')
|
||||
if s != ''
|
||||
let item['kind'] = s
|
||||
if s == 'f'
|
||||
let item['match'] = memb . '('
|
||||
endif
|
||||
endif
|
||||
|
||||
call add(matches, item)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
if len(matches) > 0
|
||||
" Skip over next [...] items
|
||||
let idx += 1
|
||||
while 1
|
||||
if complete_check()
|
||||
return matches
|
||||
endif
|
||||
if idx >= len(a:items)
|
||||
return matches " No further items, return the result.
|
||||
endif
|
||||
if a:items[idx][0] != '['
|
||||
break
|
||||
endif
|
||||
let idx += 1
|
||||
endwhile
|
||||
|
||||
" More items following. For each of the possible members find the
|
||||
" matching following members.
|
||||
return s:SearchMembers(matches, a:items[idx :], a:all)
|
||||
endif
|
||||
|
||||
" Failed to find anything.
|
||||
return []
|
||||
endfunc
|
||||
|
||||
" For matching members, find matches for following items.
|
||||
" When "all" is non-zero find all, otherwise just return 1 if there is any
|
||||
" member.
|
||||
func s:SearchMembers(matches, items, all)
|
||||
let res = []
|
||||
for i in range(len(a:matches))
|
||||
if complete_check()
|
||||
return res
|
||||
endif
|
||||
let typename = ''
|
||||
if has_key(a:matches[i], 'dict')
|
||||
if has_key(a:matches[i].dict, 'typename')
|
||||
let typename = a:matches[i].dict['typename']
|
||||
elseif has_key(a:matches[i].dict, 'typeref')
|
||||
let typename = a:matches[i].dict['typeref']
|
||||
endif
|
||||
let line = "\t" . a:matches[i].dict['cmd']
|
||||
else
|
||||
let line = a:matches[i]['tagline']
|
||||
let e = matchend(line, '\ttypename:')
|
||||
if e < 0
|
||||
let e = matchend(line, '\ttyperef:')
|
||||
endif
|
||||
if e > 0
|
||||
" Use typename field
|
||||
let typename = matchstr(line, '[^\t]*', e)
|
||||
endif
|
||||
endif
|
||||
|
||||
if typename != ''
|
||||
call extend(res, s:StructMembers(typename, a:items, a:all))
|
||||
else
|
||||
" Use the search command (the declaration itself).
|
||||
let s = match(line, '\t\zs/^')
|
||||
if s > 0
|
||||
let e = match(line, '\<' . a:matches[i]['match'] . '\>', s)
|
||||
if e > 0
|
||||
call extend(res, s:Nextitem(strpart(line, s, e - s), a:items, 0, a:all))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if a:all == 0 && len(res) > 0
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
return res
|
||||
endfunc
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
" vim: noet sw=2 sts=2
|
||||
|
@@ -2,6 +2,21 @@
|
||||
" Maintainer: Gregory Anders
|
||||
" Last Change: 2024-09-03
|
||||
" Based on: https://github.com/hashivim/vim-terraform
|
||||
" License: ISC
|
||||
"
|
||||
" Copyright (c) 2014-2016 Mark Cornick <mark@markcornick.com>
|
||||
"
|
||||
" Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
" with or without fee is hereby granted, provided that the above copyright notice
|
||||
" and this permission notice appear in all copies.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
" FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
" OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
" THIS SOFTWARE.
|
||||
|
||||
function! hcl#indentexpr(lnum)
|
||||
" Beginning of the file should have no indent
|
||||
|
192
runtime/autoload/htmlfold.vim
Normal file
192
runtime/autoload/htmlfold.vim
Normal file
@@ -0,0 +1,192 @@
|
||||
" HTML folding script, :h ft-html-plugin
|
||||
" Latest Change: 2025 May 10
|
||||
" Original Author: Aliaksei Budavei <0x000c70@gmail.com>
|
||||
|
||||
function! htmlfold#MapBalancedTags() abort
|
||||
" Describe only _a capturable-name prefix_ for start and end patterns of
|
||||
" a tag so that start tags with attributes spanning across lines can also be
|
||||
" matched with a single call of "getline()".
|
||||
let tag = '\m\c</\=\([0-9A-Za-z-]\+\)'
|
||||
let names = []
|
||||
let pairs = []
|
||||
let ends = []
|
||||
let pos = getpos('.')
|
||||
|
||||
try
|
||||
call cursor(1, 1)
|
||||
let [lnum, cnum] = searchpos(tag, 'cnW')
|
||||
|
||||
" Pair up nearest non-inlined tags in scope.
|
||||
while lnum > 0
|
||||
let name_attr = synIDattr(synID(lnum, cnum, 0), 'name')
|
||||
|
||||
if name_attr ==# 'htmlTag' || name_attr ==# 'htmlScriptTag'
|
||||
let name = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
||||
|
||||
if !empty(name)
|
||||
call insert(names, tolower(name), 0)
|
||||
call insert(pairs, [lnum, -1], 0)
|
||||
endif
|
||||
elseif name_attr ==# 'htmlEndTag'
|
||||
let name = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
||||
|
||||
if !empty(name)
|
||||
let idx = index(names, tolower(name))
|
||||
|
||||
if idx >= 0
|
||||
" Dismiss inlined balanced tags and opened-only tags.
|
||||
if pairs[idx][0] != lnum
|
||||
let pairs[idx][1] = lnum
|
||||
call add(ends, lnum)
|
||||
endif
|
||||
|
||||
" Claim a pair.
|
||||
let names[: idx] = repeat([''], (idx + 1))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
" Advance the cursor, at "<", past "</a", "<a>", etc.
|
||||
call cursor(lnum, (cnum + 3))
|
||||
let [lnum, cnum] = searchpos(tag, 'cnW')
|
||||
endwhile
|
||||
finally
|
||||
call setpos('.', pos)
|
||||
endtry
|
||||
|
||||
if empty(ends)
|
||||
return {}
|
||||
endif
|
||||
|
||||
let folds = {}
|
||||
let pending_end = ends[0]
|
||||
let level = 0
|
||||
|
||||
while !empty(pairs)
|
||||
let [start, end] = remove(pairs, -1)
|
||||
|
||||
if end < 0
|
||||
continue
|
||||
endif
|
||||
|
||||
if start >= pending_end
|
||||
" Mark a sibling tag.
|
||||
call remove(ends, 0)
|
||||
|
||||
while start >= ends[0]
|
||||
" Mark a parent tag.
|
||||
call remove(ends, 0)
|
||||
let level -= 1
|
||||
endwhile
|
||||
|
||||
let pending_end = ends[0]
|
||||
else
|
||||
" Mark a child tag.
|
||||
let level += 1
|
||||
endif
|
||||
|
||||
" Flatten the innermost inlined folds.
|
||||
let folds[start] = get(folds, start, ('>' . level))
|
||||
let folds[end] = get(folds, end, ('<' . level))
|
||||
endwhile
|
||||
|
||||
return folds
|
||||
endfunction
|
||||
|
||||
" See ":help vim9-mix".
|
||||
if !has("vim9script")
|
||||
finish
|
||||
endif
|
||||
|
||||
def! g:htmlfold#MapBalancedTags(): dict<string>
|
||||
# Describe only _a capturable-name prefix_ for start and end patterns of
|
||||
# a tag so that start tags with attributes spanning across lines can also be
|
||||
# matched with a single call of "getline()".
|
||||
const tag: string = '\m\c</\=\([0-9A-Za-z-]\+\)'
|
||||
var names: list<string> = []
|
||||
var pairs: list<list<number>> = []
|
||||
var ends: list<number> = []
|
||||
const pos: list<number> = getpos('.')
|
||||
|
||||
try
|
||||
cursor(1, 1)
|
||||
var [lnum: number, cnum: number] = searchpos(tag, 'cnW')
|
||||
|
||||
# Pair up nearest non-inlined tags in scope.
|
||||
while lnum > 0
|
||||
const name_attr: string = synIDattr(synID(lnum, cnum, 0), 'name')
|
||||
|
||||
if name_attr ==# 'htmlTag' || name_attr ==# 'htmlScriptTag'
|
||||
const name: string = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
||||
|
||||
if !empty(name)
|
||||
insert(names, tolower(name), 0)
|
||||
insert(pairs, [lnum, -1], 0)
|
||||
endif
|
||||
elseif name_attr ==# 'htmlEndTag'
|
||||
const name: string = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
||||
|
||||
if !empty(name)
|
||||
const idx: number = index(names, tolower(name))
|
||||
|
||||
if idx >= 0
|
||||
# Dismiss inlined balanced tags and opened-only tags.
|
||||
if pairs[idx][0] != lnum
|
||||
pairs[idx][1] = lnum
|
||||
add(ends, lnum)
|
||||
endif
|
||||
|
||||
# Claim a pair.
|
||||
names[: idx] = repeat([''], (idx + 1))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Advance the cursor, at "<", past "</a", "<a>", etc.
|
||||
cursor(lnum, (cnum + 3))
|
||||
[lnum, cnum] = searchpos(tag, 'cnW')
|
||||
endwhile
|
||||
finally
|
||||
setpos('.', pos)
|
||||
endtry
|
||||
|
||||
if empty(ends)
|
||||
return {}
|
||||
endif
|
||||
|
||||
var folds: dict<string> = {}
|
||||
var pending_end: number = ends[0]
|
||||
var level: number = 0
|
||||
|
||||
while !empty(pairs)
|
||||
const [start: number, end: number] = remove(pairs, -1)
|
||||
|
||||
if end < 0
|
||||
continue
|
||||
endif
|
||||
|
||||
if start >= pending_end
|
||||
# Mark a sibling tag.
|
||||
remove(ends, 0)
|
||||
|
||||
while start >= ends[0]
|
||||
# Mark a parent tag.
|
||||
remove(ends, 0)
|
||||
level -= 1
|
||||
endwhile
|
||||
|
||||
pending_end = ends[0]
|
||||
else
|
||||
# Mark a child tag.
|
||||
level += 1
|
||||
endif
|
||||
|
||||
# Flatten the innermost inlined folds.
|
||||
folds[start] = get(folds, start, ('>' .. level))
|
||||
folds[end] = get(folds, end, ('<' .. level))
|
||||
endwhile
|
||||
|
||||
return folds
|
||||
enddef
|
||||
|
||||
" vim: fdm=syntax sw=2 ts=8 noet
|
@@ -5,11 +5,11 @@
|
||||
if exists('g:loaded_clipboard_provider')
|
||||
finish
|
||||
endif
|
||||
" Default to 1. provider#clipboard#Executable() may set 2.
|
||||
" Default to 0. provider#clipboard#Executable() may set 2.
|
||||
" To force a reload:
|
||||
" :unlet g:loaded_clipboard_provider
|
||||
" :runtime autoload/provider/clipboard.vim
|
||||
let g:loaded_clipboard_provider = 1
|
||||
let g:loaded_clipboard_provider = 0
|
||||
|
||||
let s:copy = {}
|
||||
let s:paste = {}
|
||||
@@ -67,6 +67,113 @@ function! s:set_osc52() abort
|
||||
return 'OSC 52'
|
||||
endfunction
|
||||
|
||||
function! s:set_pbcopy() abort
|
||||
let s:copy['+'] = ['pbcopy']
|
||||
let s:paste['+'] = ['pbpaste']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
let s:cache_enabled = 0
|
||||
return 'pbcopy'
|
||||
endfunction
|
||||
|
||||
function! s:set_wayland() abort
|
||||
let s:copy['+'] = ['wl-copy', '--type', 'text/plain']
|
||||
let s:paste['+'] = ['wl-paste', '--no-newline']
|
||||
let s:copy['*'] = ['wl-copy', '--primary', '--type', 'text/plain']
|
||||
let s:paste['*'] = ['wl-paste', '--no-newline', '--primary']
|
||||
return 'wl-copy'
|
||||
endfunction
|
||||
|
||||
function! s:set_wayclip() abort
|
||||
let s:copy['+'] = ['waycopy']
|
||||
let s:paste['+'] = ['waypaste']
|
||||
let s:copy['*'] = ['waycopy', '-p']
|
||||
let s:paste['*'] = ['waypaste', '-p']
|
||||
return 'wayclip'
|
||||
endfunction
|
||||
|
||||
function! s:set_xsel() abort
|
||||
let s:copy['+'] = ['xsel', '--nodetach', '-i', '-b']
|
||||
let s:paste['+'] = ['xsel', '-o', '-b']
|
||||
let s:copy['*'] = ['xsel', '--nodetach', '-i', '-p']
|
||||
let s:paste['*'] = ['xsel', '-o', '-p']
|
||||
return 'xsel'
|
||||
endfunction
|
||||
|
||||
function! s:set_xclip() abort
|
||||
let s:copy['+'] = ['xclip', '-quiet', '-i', '-selection', 'clipboard']
|
||||
let s:paste['+'] = ['xclip', '-o', '-selection', 'clipboard']
|
||||
let s:copy['*'] = ['xclip', '-quiet', '-i', '-selection', 'primary']
|
||||
let s:paste['*'] = ['xclip', '-o', '-selection', 'primary']
|
||||
return 'xclip'
|
||||
endfunction
|
||||
|
||||
function! s:set_lemonade() abort
|
||||
let s:copy['+'] = ['lemonade', 'copy']
|
||||
let s:paste['+'] = ['lemonade', 'paste']
|
||||
let s:copy['*'] = ['lemonade', 'copy']
|
||||
let s:paste['*'] = ['lemonade', 'paste']
|
||||
return 'lemonade'
|
||||
endfunction
|
||||
|
||||
function! s:set_doitclient() abort
|
||||
let s:copy['+'] = ['doitclient', 'wclip']
|
||||
let s:paste['+'] = ['doitclient', 'wclip', '-r']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'doitclient'
|
||||
endfunction
|
||||
|
||||
function! s:set_win32yank() abort
|
||||
if has('wsl') && getftype(exepath('win32yank.exe')) == 'link'
|
||||
let win32yank = resolve(exepath('win32yank.exe'))
|
||||
else
|
||||
let win32yank = 'win32yank.exe'
|
||||
endif
|
||||
let s:copy['+'] = [win32yank, '-i', '--crlf']
|
||||
let s:paste['+'] = [win32yank, '-o', '--lf']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'win32yank'
|
||||
endfunction
|
||||
|
||||
function! s:set_putclip() abort
|
||||
let s:copy['+'] = ['putclip']
|
||||
let s:paste['+'] = ['getclip']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'putclip'
|
||||
endfunction
|
||||
|
||||
function! s:set_clip() abort
|
||||
let s:copy['+'] = ['clip']
|
||||
let s:paste['+'] = ['powershell', '-NoProfile', '-NoLogo', '-Command', 'Get-Clipboard']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'clip'
|
||||
endfunction
|
||||
|
||||
function! s:set_termux() abort
|
||||
let s:copy['+'] = ['termux-clipboard-set']
|
||||
let s:paste['+'] = ['termux-clipboard-get']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'termux-clipboard'
|
||||
endfunction
|
||||
|
||||
function! s:set_tmux() abort
|
||||
let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V']))
|
||||
if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0])
|
||||
let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-']
|
||||
else
|
||||
let s:copy['+'] = ['tmux', 'load-buffer', '-']
|
||||
endif
|
||||
let s:paste['+'] = ['tmux', 'save-buffer', '-']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'tmux'
|
||||
endfunction
|
||||
|
||||
let s:cache_enabled = 1
|
||||
let s:err = ''
|
||||
|
||||
@@ -78,9 +185,34 @@ function! provider#clipboard#Executable() abort
|
||||
" Setting g:clipboard to v:false explicitly opts-in to using the "builtin" clipboard providers below
|
||||
if exists('g:clipboard') && g:clipboard isnot# v:false
|
||||
if v:t_string ==# type(g:clipboard)
|
||||
" Handle string form of g:clipboard for all builtin providers
|
||||
if 'osc52' == g:clipboard
|
||||
" User opted-in to OSC 52 by manually setting g:clipboard.
|
||||
return s:set_osc52()
|
||||
elseif 'pbcopy' == g:clipboard
|
||||
return s:set_pbcopy()
|
||||
elseif 'wl-copy' == g:clipboard
|
||||
return s:set_wayland()
|
||||
elseif 'wayclip' == g:clipboard
|
||||
return s:set_wayclip()
|
||||
elseif 'xsel' == g:clipboard
|
||||
return s:set_xsel()
|
||||
elseif 'xclip' == g:clipboard
|
||||
return s:set_xclip()
|
||||
elseif 'lemonade' == g:clipboard
|
||||
return s:set_lemonade()
|
||||
elseif 'doitclient' == g:clipboard
|
||||
return s:set_doitclient()
|
||||
elseif 'win32yank' == g:clipboard
|
||||
return s:set_win32yank()
|
||||
elseif 'putclip' == g:clipboard
|
||||
return s:set_putclip()
|
||||
elseif 'clip' == g:clipboard
|
||||
return s:set_clip()
|
||||
elseif 'termux' == g:clipboard
|
||||
return s:set_termux()
|
||||
elseif 'tmux' == g:clipboard
|
||||
return s:set_tmux()
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -102,88 +234,29 @@ function! provider#clipboard#Executable() abort
|
||||
let s:cache_enabled = get(g:clipboard, 'cache_enabled', 0)
|
||||
return get(g:clipboard, 'name', 'g:clipboard')
|
||||
elseif has('mac')
|
||||
let s:copy['+'] = ['pbcopy']
|
||||
let s:paste['+'] = ['pbpaste']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
let s:cache_enabled = 0
|
||||
return 'pbcopy'
|
||||
return s:set_pbcopy()
|
||||
elseif !empty($WAYLAND_DISPLAY) && executable('wl-copy') && executable('wl-paste')
|
||||
let s:copy['+'] = ['wl-copy', '--type', 'text/plain']
|
||||
let s:paste['+'] = ['wl-paste', '--no-newline']
|
||||
let s:copy['*'] = ['wl-copy', '--primary', '--type', 'text/plain']
|
||||
let s:paste['*'] = ['wl-paste', '--no-newline', '--primary']
|
||||
return 'wl-copy'
|
||||
return s:set_wayland()
|
||||
elseif !empty($WAYLAND_DISPLAY) && executable('waycopy') && executable('waypaste')
|
||||
let s:copy['+'] = ['waycopy', '-t', 'text/plain']
|
||||
let s:paste['+'] = ['waypaste', '-t', 'text/plain']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'wayclip'
|
||||
return s:set_wayclip()
|
||||
elseif !empty($DISPLAY) && executable('xsel') && s:cmd_ok('xsel -o -b')
|
||||
let s:copy['+'] = ['xsel', '--nodetach', '-i', '-b']
|
||||
let s:paste['+'] = ['xsel', '-o', '-b']
|
||||
let s:copy['*'] = ['xsel', '--nodetach', '-i', '-p']
|
||||
let s:paste['*'] = ['xsel', '-o', '-p']
|
||||
return 'xsel'
|
||||
return s:set_xsel()
|
||||
elseif !empty($DISPLAY) && executable('xclip')
|
||||
let s:copy['+'] = ['xclip', '-quiet', '-i', '-selection', 'clipboard']
|
||||
let s:paste['+'] = ['xclip', '-o', '-selection', 'clipboard']
|
||||
let s:copy['*'] = ['xclip', '-quiet', '-i', '-selection', 'primary']
|
||||
let s:paste['*'] = ['xclip', '-o', '-selection', 'primary']
|
||||
return 'xclip'
|
||||
return s:set_xclip()
|
||||
elseif executable('lemonade')
|
||||
let s:copy['+'] = ['lemonade', 'copy']
|
||||
let s:paste['+'] = ['lemonade', 'paste']
|
||||
let s:copy['*'] = ['lemonade', 'copy']
|
||||
let s:paste['*'] = ['lemonade', 'paste']
|
||||
return 'lemonade'
|
||||
return s:set_lemonade()
|
||||
elseif executable('doitclient')
|
||||
let s:copy['+'] = ['doitclient', 'wclip']
|
||||
let s:paste['+'] = ['doitclient', 'wclip', '-r']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'doitclient'
|
||||
return s:set_doitclient()
|
||||
elseif executable('win32yank.exe')
|
||||
if has('wsl') && getftype(exepath('win32yank.exe')) == 'link'
|
||||
let win32yank = resolve(exepath('win32yank.exe'))
|
||||
else
|
||||
let win32yank = 'win32yank.exe'
|
||||
endif
|
||||
let s:copy['+'] = [win32yank, '-i', '--crlf']
|
||||
let s:paste['+'] = [win32yank, '-o', '--lf']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'win32yank'
|
||||
return s:set_win32yank()
|
||||
elseif executable('putclip') && executable('getclip')
|
||||
let s:copy['+'] = ['putclip']
|
||||
let s:paste['+'] = ['getclip']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'putclip'
|
||||
return s:set_putclip()
|
||||
elseif executable('clip') && executable('powershell')
|
||||
let s:copy['+'] = ['clip']
|
||||
let s:paste['+'] = ['powershell', '-NoProfile', '-NoLogo', '-Command', 'Get-Clipboard']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'clip'
|
||||
return s:set_clip()
|
||||
elseif executable('termux-clipboard-set')
|
||||
let s:copy['+'] = ['termux-clipboard-set']
|
||||
let s:paste['+'] = ['termux-clipboard-get']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'termux-clipboard'
|
||||
return s:set_termux()
|
||||
elseif executable('tmux') && (!empty($TMUX) || 0 == jobwait([jobstart(['tmux', 'list-buffers'])], 2000)[0])
|
||||
let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V']))
|
||||
if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0])
|
||||
let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-']
|
||||
else
|
||||
let s:copy['+'] = ['tmux', 'load-buffer', '-']
|
||||
endif
|
||||
let s:paste['+'] = ['tmux', 'save-buffer', '-']
|
||||
let s:copy['*'] = s:copy['+']
|
||||
let s:paste['*'] = s:paste['+']
|
||||
return 'tmux'
|
||||
return s:set_tmux()
|
||||
elseif get(get(g:, 'termfeatures', {}), 'osc52') && &clipboard ==# ''
|
||||
" Don't use OSC 52 when 'clipboard' is set. It can be slow and cause a lot
|
||||
" of user prompts. Users can opt-in to it by setting g:clipboard manually.
|
||||
@@ -195,13 +268,11 @@ function! provider#clipboard#Executable() abort
|
||||
endfunction
|
||||
|
||||
function! s:clipboard.get(reg) abort
|
||||
if type(s:paste[a:reg]) == v:t_func
|
||||
return s:paste[a:reg]()
|
||||
elseif s:selections[a:reg].owner > 0
|
||||
if s:selections[a:reg].owner > 0
|
||||
return s:selections[a:reg].data
|
||||
end
|
||||
|
||||
let clipboard_data = s:try_cmd(s:paste[a:reg])
|
||||
let clipboard_data = type(s:paste[a:reg]) == v:t_func ? s:paste[a:reg]() : s:try_cmd(s:paste[a:reg])
|
||||
if match(&clipboard, '\v(unnamed|unnamedplus)') >= 0
|
||||
\ && type(clipboard_data) == v:t_list
|
||||
\ && get(s:selections[a:reg].data, 0, []) ==# clipboard_data
|
||||
@@ -221,13 +292,12 @@ function! s:clipboard.set(lines, regtype, reg) abort
|
||||
return 0
|
||||
end
|
||||
|
||||
if type(s:copy[a:reg]) == v:t_func
|
||||
call s:copy[a:reg](a:lines, a:regtype)
|
||||
return 0
|
||||
end
|
||||
|
||||
if s:cache_enabled == 0
|
||||
call s:try_cmd(s:copy[a:reg], a:lines)
|
||||
if s:cache_enabled == 0 || type(s:copy[a:reg]) == v:t_func
|
||||
if type(s:copy[a:reg]) == v:t_func
|
||||
call s:copy[a:reg](a:lines, a:regtype)
|
||||
else
|
||||
call s:try_cmd(s:copy[a:reg], a:lines)
|
||||
endif
|
||||
"Cache it anyway we can compare it later to get regtype of the yank
|
||||
let s:selections[a:reg] = copy(s:selection)
|
||||
let s:selections[a:reg].data = [a:lines, a:regtype]
|
||||
@@ -284,4 +354,4 @@ function! provider#clipboard#Call(method, args) abort
|
||||
endfunction
|
||||
|
||||
" eval_has_provider() decides based on this variable.
|
||||
let g:loaded_clipboard_provider = empty(provider#clipboard#Executable()) ? 1 : 2
|
||||
let g:loaded_clipboard_provider = empty(provider#clipboard#Executable()) ? 0 : 2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
if exists('g:loaded_node_provider')
|
||||
finish
|
||||
endif
|
||||
let g:loaded_node_provider = 1
|
||||
let g:loaded_node_provider = 0
|
||||
|
||||
function! s:is_minimum_version(version, min_version) abort
|
||||
if empty(a:version)
|
||||
@@ -152,7 +152,7 @@ endfunction
|
||||
|
||||
let s:err = ''
|
||||
let [s:prog, s:_] = provider#node#Detect()
|
||||
let g:loaded_node_provider = empty(s:prog) ? 1 : 2
|
||||
let g:loaded_node_provider = empty(s:prog) ? 0 : 2
|
||||
|
||||
if g:loaded_node_provider != 2
|
||||
let s:err = 'Cannot find the "neovim" node package. Try :checkhealth'
|
||||
|
@@ -11,5 +11,5 @@ function! provider#perl#Require(host) abort
|
||||
endfunction
|
||||
|
||||
let s:prog = v:lua.vim.provider.perl.detect()
|
||||
let g:loaded_perl_provider = empty(s:prog) ? 1 : 2
|
||||
let g:loaded_perl_provider = empty(s:prog) ? 0 : 2
|
||||
call v:lua.require'vim.provider.perl'.start()
|
||||
|
@@ -11,5 +11,5 @@ function! provider#python3#Require(host) abort
|
||||
endfunction
|
||||
|
||||
let s:prog = v:lua.vim.provider.python.detect_by_module('neovim')
|
||||
let g:loaded_python3_provider = empty(s:prog) ? 1 : 2
|
||||
let g:loaded_python3_provider = empty(s:prog) ? 0 : 2
|
||||
call v:lua.require'vim.provider.python'.start()
|
||||
|
@@ -11,6 +11,6 @@ function! provider#ruby#Call(method, args) abort
|
||||
endfunction
|
||||
|
||||
let s:prog = v:lua.vim.provider.ruby.detect()
|
||||
let g:loaded_ruby_provider = empty(s:prog) ? 1 : 2
|
||||
let g:loaded_ruby_provider = empty(s:prog) ? 0 : 2
|
||||
let s:plugin_path = expand('<sfile>:p:h') . '/script_host.rb'
|
||||
call v:lua.require'vim.provider.ruby'.start(s:plugin_path)
|
||||
|
@@ -1,5 +1,8 @@
|
||||
" Author: Stephen Sugden <stephen@stephensugden.com>
|
||||
" Last Modified: 2023-09-11
|
||||
" Last Change:
|
||||
" 2025 Mar 31 by Vim project (rename s:RustfmtConfigOptions())
|
||||
" 2025 Jul 14 by Vim project (don't parse rustfmt version automatically #17745)
|
||||
"
|
||||
" Adapted from https://github.com/fatih/vim-go
|
||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||
@@ -21,6 +24,12 @@ if !exists("g:rustfmt_fail_silently")
|
||||
endif
|
||||
|
||||
function! rustfmt#DetectVersion()
|
||||
let s:rustfmt_version = "0"
|
||||
let s:rustfmt_help = ""
|
||||
let s:rustfmt_unstable_features = ""
|
||||
if !get(g:, 'rustfmt_detect_version', 0)
|
||||
return s:rustfmt_version
|
||||
endif
|
||||
" Save rustfmt '--help' for feature inspection
|
||||
silent let s:rustfmt_help = system(g:rustfmt_command . " --help")
|
||||
let s:rustfmt_unstable_features = s:rustfmt_help =~# "--unstable-features"
|
||||
@@ -29,9 +38,7 @@ function! rustfmt#DetectVersion()
|
||||
silent let l:rustfmt_version_full = system(g:rustfmt_command . " --version")
|
||||
let l:rustfmt_version_list = matchlist(l:rustfmt_version_full,
|
||||
\ '\vrustfmt ([0-9]+[.][0-9]+[.][0-9]+)')
|
||||
if len(l:rustfmt_version_list) < 3
|
||||
let s:rustfmt_version = "0"
|
||||
else
|
||||
if len(l:rustfmt_version_list) >= 3
|
||||
let s:rustfmt_version = l:rustfmt_version_list[1]
|
||||
endif
|
||||
return s:rustfmt_version
|
||||
@@ -61,7 +68,13 @@ function! s:RustfmtWriteMode()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RustfmtConfigOptions()
|
||||
function! rustfmt#RustfmtConfigOptions()
|
||||
let default = '--edition 2018'
|
||||
|
||||
if !get(g:, 'rustfmt_find_toml', 0)
|
||||
return default
|
||||
endif
|
||||
|
||||
let l:rustfmt_toml = findfile('rustfmt.toml', expand('%:p:h') . ';')
|
||||
if l:rustfmt_toml !=# ''
|
||||
return '--config-path '.shellescape(fnamemodify(l:rustfmt_toml, ":p"))
|
||||
@@ -73,7 +86,7 @@ function! s:RustfmtConfigOptions()
|
||||
endif
|
||||
|
||||
" Default to edition 2018 in case no rustfmt.toml was found.
|
||||
return '--edition 2018'
|
||||
return default
|
||||
endfunction
|
||||
|
||||
function! s:RustfmtCommandRange(filename, line1, line2)
|
||||
@@ -84,7 +97,7 @@ function! s:RustfmtCommandRange(filename, line1, line2)
|
||||
|
||||
let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
|
||||
let l:write_mode = s:RustfmtWriteMode()
|
||||
let l:rustfmt_config = s:RustfmtConfigOptions()
|
||||
let l:rustfmt_config = rustfmt#RustfmtConfigOptions()
|
||||
|
||||
" FIXME: When --file-lines gets to be stable, add version range checking
|
||||
" accordingly.
|
||||
@@ -99,7 +112,7 @@ endfunction
|
||||
|
||||
function! s:RustfmtCommand()
|
||||
let write_mode = g:rustfmt_emit_files ? '--emit=stdout' : '--write-mode=display'
|
||||
let config = s:RustfmtConfigOptions()
|
||||
let config = rustfmt#RustfmtConfigOptions()
|
||||
return join([g:rustfmt_command, write_mode, config, g:rustfmt_options])
|
||||
endfunction
|
||||
|
||||
|
@@ -12,6 +12,11 @@
|
||||
" 2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
|
||||
" 2025 Mar 01 by Vim Project: fix syntax error in tar#Read()
|
||||
" 2025 Mar 02 by Vim Project: escape the filename before using :read
|
||||
" 2025 Mar 02 by Vim Project: determine the compression using readblob()
|
||||
" instead of shelling out to file(1)
|
||||
" 2025 Apr 16 by Vim Project: decouple from netrw by adding s:WinPath()
|
||||
" 2025 May 19 by Vim Project: restore working directory after read/write
|
||||
" 2025 Jul 13 by Vim Project: warn with path traversal attacks
|
||||
"
|
||||
" Contains many ideas from Michael Toren's <tar.vim>
|
||||
"
|
||||
@@ -30,9 +35,9 @@ if &cp || exists("g:loaded_tar")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_tar= "v32b"
|
||||
if v:version < 702
|
||||
if !has('nvim-0.12') && v:version < 900
|
||||
echohl WarningMsg
|
||||
echo "***warning*** this version of tar needs vim 7.2"
|
||||
echo "***warning*** this version of tar needs vim 9.0"
|
||||
echohl Normal
|
||||
finish
|
||||
endif
|
||||
@@ -42,10 +47,10 @@ set cpo&vim
|
||||
" ---------------------------------------------------------------------
|
||||
" Default Settings: {{{1
|
||||
if !exists("g:tar_browseoptions")
|
||||
let g:tar_browseoptions= "Ptf"
|
||||
let g:tar_browseoptions= "tf"
|
||||
endif
|
||||
if !exists("g:tar_readoptions")
|
||||
let g:tar_readoptions= "pPxf"
|
||||
let g:tar_readoptions= "pxf"
|
||||
endif
|
||||
if !exists("g:tar_cmd")
|
||||
let g:tar_cmd= "tar"
|
||||
@@ -54,6 +59,7 @@ if !exists("g:tar_writeoptions")
|
||||
let g:tar_writeoptions= "uf"
|
||||
endif
|
||||
if !exists("g:tar_delfile")
|
||||
" Note: not supported on BSD
|
||||
let g:tar_delfile="--delete -f"
|
||||
endif
|
||||
if !exists("g:netrw_cygwin")
|
||||
@@ -102,10 +108,26 @@ if !exists("g:tar_shq")
|
||||
endif
|
||||
endif
|
||||
|
||||
let g:tar_secure=' -- '
|
||||
let g:tar_leading_pat='^\%([.]\{,2\}/\)\+'
|
||||
|
||||
" ----------------
|
||||
" Functions: {{{1
|
||||
" ----------------
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" s:Msg: {{{2
|
||||
fun! s:Msg(func, severity, msg)
|
||||
redraw!
|
||||
if a:severity =~? 'error'
|
||||
echohl Error
|
||||
else
|
||||
echohl WarningMsg
|
||||
endif
|
||||
echo $"***{a:severity}*** ({a:func}) {a:msg}"
|
||||
echohl None
|
||||
endfunc
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" tar#Browse: {{{2
|
||||
fun! tar#Browse(tarfile)
|
||||
@@ -114,16 +136,14 @@ fun! tar#Browse(tarfile)
|
||||
|
||||
" sanity checks
|
||||
if !executable(g:tar_cmd)
|
||||
redraw!
|
||||
echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
|
||||
call s:Msg('tar#Browse', 'error', $"{g:tar_cmd} not available on your system")
|
||||
let &report= repkeep
|
||||
return
|
||||
endif
|
||||
if !filereadable(a:tarfile)
|
||||
if a:tarfile !~# '^\a\+://'
|
||||
" if it's an url, don't complain, let url-handlers such as vim do its thing
|
||||
redraw!
|
||||
echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
|
||||
call s:Msg('tar#Browse', 'error', $"File not readable<{a:tarfile}>")
|
||||
endif
|
||||
let &report= repkeep
|
||||
return
|
||||
@@ -144,7 +164,7 @@ fun! tar#Browse(tarfile)
|
||||
let lastline= line("$")
|
||||
call setline(lastline+1,'" tar.vim version '.g:loaded_tar)
|
||||
call setline(lastline+2,'" Browsing tarfile '.a:tarfile)
|
||||
call setline(lastline+3,'" Select a file with cursor and press ENTER')
|
||||
call setline(lastline+3,'" Select a file with cursor and press ENTER, "x" to extract a file')
|
||||
keepj $put =''
|
||||
keepj sil! 0d
|
||||
keepj $
|
||||
@@ -161,23 +181,19 @@ fun! tar#Browse(tarfile)
|
||||
|
||||
elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' ||
|
||||
\ tarfile =~# '\.\(tzst\)$' || tarfile =~# '\.\(tlz4\)$'
|
||||
if has("unix") && executable("file")
|
||||
let filekind= system("file ".shellescape(tarfile,1))
|
||||
else
|
||||
let filekind= ""
|
||||
endif
|
||||
let header= s:Header(tarfile)
|
||||
|
||||
if filekind =~ "bzip2"
|
||||
if header =~? 'bzip2'
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
elseif filekind =~ "bzip3"
|
||||
elseif header =~? 'bzip3'
|
||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
elseif filekind =~ "XZ"
|
||||
elseif header =~? 'xz'
|
||||
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
elseif filekind =~ "Zstandard"
|
||||
elseif header =~? 'zstd'
|
||||
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
elseif filekind =~ "LZ4"
|
||||
elseif header =~? 'lz4'
|
||||
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
else
|
||||
elseif header =~? 'gzip'
|
||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||
endif
|
||||
|
||||
@@ -203,28 +219,18 @@ fun! tar#Browse(tarfile)
|
||||
exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1)
|
||||
endif
|
||||
if v:shell_error != 0
|
||||
redraw!
|
||||
echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
|
||||
call s:Msg('tar#Browse', 'warning', $"please check your g:tar_browseoptions '<{g:tar_browseoptions}>'")
|
||||
return
|
||||
endif
|
||||
"
|
||||
" The following should not be neccessary, since in case of errors the
|
||||
" previous if statement should have caught the problem (because tar exited
|
||||
" with a non-zero exit code).
|
||||
" if line("$") == curlast || ( line("$") == (curlast + 1) &&
|
||||
" \ getline("$") =~# '\c\<\%(warning\|error\|inappropriate\|unrecognized\)\>' &&
|
||||
" \ getline("$") =~ '\s' )
|
||||
" redraw!
|
||||
" echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
|
||||
" keepj sil! %d
|
||||
" let eikeep= &ei
|
||||
" set ei=BufReadCmd,FileReadCmd
|
||||
" exe "r ".fnameescape(a:tarfile)
|
||||
" let &ei= eikeep
|
||||
" keepj sil! 1d
|
||||
" call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
|
||||
" return
|
||||
" endif
|
||||
|
||||
" remove tar: Removing leading '/' from member names
|
||||
" Note: the message could be localized
|
||||
if search('^tar: ') > 0 || search(g:tar_leading_pat) > 0
|
||||
call append(3,'" Note: Path Traversal Attack detected!')
|
||||
let b:leading_slash = 1
|
||||
" remove the message output
|
||||
sil g/^tar: /d
|
||||
endif
|
||||
|
||||
" set up maps supported for tar
|
||||
setlocal noma nomod ro
|
||||
@@ -243,12 +249,7 @@ fun! s:TarBrowseSelect()
|
||||
let repkeep= &report
|
||||
set report=10
|
||||
let fname= getline(".")
|
||||
|
||||
if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
|
||||
redraw!
|
||||
echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
|
||||
return
|
||||
endif
|
||||
let ls= get(b:, 'leading_slash', 0)
|
||||
|
||||
" sanity check
|
||||
if fname =~ '^"'
|
||||
@@ -270,7 +271,8 @@ fun! s:TarBrowseSelect()
|
||||
wincmd _
|
||||
endif
|
||||
let s:tblfile_{winnr()}= curfile
|
||||
call tar#Read("tarfile:".tarfile.'::'.fname,1)
|
||||
let b:leading_slash= ls
|
||||
call tar#Read("tarfile:".tarfile.'::'.fname)
|
||||
filetype detect
|
||||
set nomod
|
||||
exe 'com! -buffer -nargs=? -complete=file TarDiff :call tar#Diff(<q-args>,"'.fnameescape(fname).'")'
|
||||
@@ -280,26 +282,18 @@ endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" tar#Read: {{{2
|
||||
fun! tar#Read(fname,mode)
|
||||
fun! tar#Read(fname)
|
||||
let repkeep= &report
|
||||
set report=10
|
||||
let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
|
||||
let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
|
||||
" be careful not to execute special crafted files
|
||||
let escape_file = fname->fnameescape()
|
||||
|
||||
" changing the directory to the temporary earlier to allow tar to extract the file with permissions intact
|
||||
if !exists("*mkdir")
|
||||
redraw!
|
||||
echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
|
||||
let &report= repkeep
|
||||
return
|
||||
endif
|
||||
let escape_file = fname->substitute(g:tar_leading_pat, '', '')->fnameescape()
|
||||
|
||||
let curdir= getcwd()
|
||||
let b:curdir= curdir
|
||||
let tmpdir= tempname()
|
||||
let b:curdir= tmpdir
|
||||
let b:tmpdir= curdir
|
||||
let b:tmpdir= tmpdir
|
||||
if tmpdir =~ '\.'
|
||||
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
||||
endif
|
||||
@@ -307,10 +301,9 @@ fun! tar#Read(fname,mode)
|
||||
|
||||
" attempt to change to the indicated directory
|
||||
try
|
||||
exe "cd ".fnameescape(tmpdir)
|
||||
exe "lcd ".fnameescape(tmpdir)
|
||||
catch /^Vim\%((\a\+)\)\=:E344/
|
||||
redraw!
|
||||
echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
|
||||
call s:Msg('tar#Read', 'error', "cannot lcd to temporary directory")
|
||||
let &report= repkeep
|
||||
return
|
||||
endtry
|
||||
@@ -320,7 +313,7 @@ fun! tar#Read(fname,mode)
|
||||
call s:Rmdir("_ZIPVIM_")
|
||||
endif
|
||||
call mkdir("_ZIPVIM_")
|
||||
cd _ZIPVIM_
|
||||
lcd _ZIPVIM_
|
||||
|
||||
if has("win32unix") && executable("cygpath")
|
||||
" assuming cygwin
|
||||
@@ -333,7 +326,7 @@ fun! tar#Read(fname,mode)
|
||||
elseif fname =~ '\.bz3$' && executable("bz3cat")
|
||||
let decmp= "|bz3cat"
|
||||
let doro = 1
|
||||
elseif fname =~ '\.t\=gz$' && executable("zcat")
|
||||
elseif fname =~ '\.t\=gz$' && executable("zcat")
|
||||
let decmp= "|zcat"
|
||||
let doro = 1
|
||||
elseif fname =~ '\.lzma$' && executable("lzcat")
|
||||
@@ -356,72 +349,66 @@ fun! tar#Read(fname,mode)
|
||||
endif
|
||||
endif
|
||||
|
||||
if exists("g:tar_secure")
|
||||
let tar_secure= " -- "
|
||||
else
|
||||
let tar_secure= " "
|
||||
endif
|
||||
|
||||
if tarfile =~# '\.bz2$'
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif tarfile =~# '\.bz3$'
|
||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif tarfile =~# '\.\(gz\)$'
|
||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
|
||||
if has("unix") && executable("file")
|
||||
let filekind= system("file ".shellescape(tarfile,1))
|
||||
else
|
||||
let filekind= ""
|
||||
endif
|
||||
if filekind =~ "bzip2"
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
let filekind= s:Header(tarfile)
|
||||
if filekind =~? "bzip2"
|
||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif filekind =~ "bzip3"
|
||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif filekind =~ "XZ"
|
||||
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
elseif filekind =~? "xz"
|
||||
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif filekind =~ "Zstandard"
|
||||
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
elseif filekind =~? "zstd"
|
||||
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
else
|
||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
elseif filekind =~? "gzip"
|
||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
endif
|
||||
|
||||
elseif tarfile =~# '\.lrp$'
|
||||
exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif tarfile =~# '\.lzma$'
|
||||
exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif tarfile =~# '\.\(xz\|txz\)$'
|
||||
exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
elseif tarfile =~# '\.\(lz4\|tlz4\)$'
|
||||
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
else
|
||||
if tarfile =~ '^\s*-'
|
||||
" A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
|
||||
let tarfile = substitute(tarfile, '-', './-', '')
|
||||
endif
|
||||
exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".tar_secure.shellescape(fname,1).decmp
|
||||
exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".g:tar_secure.shellescape(fname,1).decmp
|
||||
exe "read ".escape_file
|
||||
endif
|
||||
if get(b:, 'leading_slash', 0)
|
||||
sil g/^tar: /d
|
||||
endif
|
||||
|
||||
redraw!
|
||||
|
||||
if v:shell_error != 0
|
||||
cd ..
|
||||
if v:shell_error != 0
|
||||
lcd ..
|
||||
call s:Rmdir("_ZIPVIM_")
|
||||
exe "cd ".fnameescape(curdir)
|
||||
echohl Error | echo "***error*** (tar#Read) sorry, unable to open or extract ".tarfile." with ".fname | echohl None
|
||||
exe "lcd ".fnameescape(curdir)
|
||||
call s:Msg('tar#Read', 'error', $"sorry, unable to open or extract {tarfile} with {fname}")
|
||||
endif
|
||||
|
||||
if doro
|
||||
@@ -430,40 +417,54 @@ if v:shell_error != 0
|
||||
endif
|
||||
|
||||
let b:tarfile= a:fname
|
||||
exe "file tarfile::".fnameescape(fname)
|
||||
|
||||
" cleanup
|
||||
keepj sil! 0d
|
||||
set nomod
|
||||
|
||||
let &report= repkeep
|
||||
exe "lcd ".fnameescape(curdir)
|
||||
silent exe "file tarfile::". fname->fnameescape()
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" tar#Write: {{{2
|
||||
fun! tar#Write(fname)
|
||||
let pwdkeep= getcwd()
|
||||
let repkeep= &report
|
||||
set report=10
|
||||
" temporary buffer variable workaround because too fucking tired. but it works now
|
||||
let curdir= b:curdir
|
||||
let tmpdir= b:tmpdir
|
||||
|
||||
if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-'
|
||||
redraw!
|
||||
echohl WarningMsg | echo '***warning*** (tar#Write) rejecting tarfile member<'.a:fname.'> because of embedded "-"'
|
||||
return
|
||||
endif
|
||||
|
||||
" sanity checks
|
||||
if !executable(g:tar_cmd)
|
||||
redraw!
|
||||
let &report= repkeep
|
||||
return
|
||||
endif
|
||||
|
||||
let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
|
||||
let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')
|
||||
|
||||
if get(b:, 'leading_slash', 0)
|
||||
call s:Msg('tar#Write', 'error', $"sorry, not attempting to update {tarfile} with {fname}")
|
||||
let &report= repkeep
|
||||
return
|
||||
endif
|
||||
|
||||
if !isdirectory(fnameescape(tmpdir))
|
||||
call mkdir(fnameescape(tmpdir), 'p')
|
||||
endif
|
||||
exe $"lcd {fnameescape(tmpdir)}"
|
||||
if isdirectory("_ZIPVIM_")
|
||||
call s:Rmdir("_ZIPVIM_")
|
||||
endif
|
||||
call mkdir("_ZIPVIM_")
|
||||
lcd _ZIPVIM_
|
||||
let dir = fnamemodify(fname, ':p:h')
|
||||
if dir !~# '_ZIPVIM_$'
|
||||
call mkdir(dir)
|
||||
endif
|
||||
|
||||
" handle compressed archives
|
||||
if tarfile =~# '\.bz2'
|
||||
call system("bzip2 -d -- ".shellescape(tarfile,0))
|
||||
@@ -499,10 +500,10 @@ fun! tar#Write(fname)
|
||||
let tarfile = substitute(tarfile,'\.lzma','','e')
|
||||
let compress= "lzma -- ".shellescape(tarfile,0)
|
||||
endif
|
||||
" Note: no support for name.tar.tbz/.txz/.tgz/.tlz4/.tzst
|
||||
|
||||
if v:shell_error != 0
|
||||
redraw!
|
||||
echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
|
||||
call s:Msg('tar#Write', 'error', $"sorry, unable to update {tarfile} with {fname}")
|
||||
else
|
||||
|
||||
if fname =~ '/'
|
||||
@@ -520,28 +521,22 @@ fun! tar#Write(fname)
|
||||
let tarfile = substitute(tarfile, '-', './-', '')
|
||||
endif
|
||||
|
||||
if exists("g:tar_secure")
|
||||
let tar_secure= " -- "
|
||||
else
|
||||
let tar_secure= " "
|
||||
endif
|
||||
exe "w! ".fnameescape(fname)
|
||||
" don't overwrite a file forcefully
|
||||
exe "w ".fnameescape(fname)
|
||||
if has("win32unix") && executable("cygpath")
|
||||
let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e')
|
||||
endif
|
||||
|
||||
" delete old file from tarfile
|
||||
call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
|
||||
" Note: BSD tar does not support --delete flag
|
||||
call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).g:tar_secure.shellescape(fname,0))
|
||||
if v:shell_error != 0
|
||||
redraw!
|
||||
echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
|
||||
call s:Msg('tar#Write', 'error', $"sorry, unable to update {fnameescape(tarfile)} with {fnameescape(fname)} --delete not supported?")
|
||||
else
|
||||
|
||||
" update tarfile with new file
|
||||
call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
|
||||
call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).g:tar_secure.shellescape(fname,0))
|
||||
if v:shell_error != 0
|
||||
redraw!
|
||||
echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
|
||||
call s:Msg('tar#Write', 'error', $"sorry, unable to update {fnameescape(tarfile)} with {fnameescape(fname)}")
|
||||
elseif exists("compress")
|
||||
call system(compress)
|
||||
if exists("tgz")
|
||||
@@ -567,9 +562,9 @@ fun! tar#Write(fname)
|
||||
endif
|
||||
|
||||
" cleanup and restore current directory
|
||||
cd ..
|
||||
lcd ..
|
||||
call s:Rmdir("_ZIPVIM_")
|
||||
exe "cd ".fnameescape(curdir)
|
||||
exe "lcd ".fnameescape(pwdkeep)
|
||||
setlocal nomod
|
||||
|
||||
let &report= repkeep
|
||||
@@ -582,6 +577,7 @@ fun! tar#Diff(userfname,fname)
|
||||
if a:userfname != ""
|
||||
let fname= a:userfname
|
||||
endif
|
||||
exe "lcd ".fnameescape(b:tmpdir). '/_ZIPVIM_'
|
||||
if filereadable(fname)
|
||||
" sets current file (from tarball) for diff'ing
|
||||
" splits window vertically
|
||||
@@ -605,12 +601,6 @@ fun! tar#Extract()
|
||||
set report=10
|
||||
let fname= getline(".")
|
||||
|
||||
if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
|
||||
redraw!
|
||||
echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
|
||||
return
|
||||
endif
|
||||
|
||||
" sanity check
|
||||
if fname =~ '^"'
|
||||
let &report= repkeep
|
||||
@@ -620,20 +610,20 @@ fun! tar#Extract()
|
||||
let tarball = expand("%")
|
||||
let tarbase = substitute(tarball,'\..*$','','')
|
||||
|
||||
let extractcmd= netrw#WinPath(g:tar_extractcmd)
|
||||
let extractcmd= s:WinPath(g:tar_extractcmd)
|
||||
if filereadable(tarbase.".tar")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
echo "***note*** successfully extracted ". fname
|
||||
endif
|
||||
|
||||
elseif filereadable(tarbase.".tgz")
|
||||
let extractcmd= substitute(extractcmd,"-","-z","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tgz ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tgz {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -642,7 +632,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-z","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.gz {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -651,7 +641,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-j","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tbz {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -660,7 +650,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-j","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz2 {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -669,7 +659,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-j","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz3 ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz3 {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -678,7 +668,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-J","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.txz {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -687,7 +677,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-J","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.xz {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -696,7 +686,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","--zstd","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzst ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tzst {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -705,7 +695,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","--zstd","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.zst {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -714,7 +704,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-I lz4","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tlz4 ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tlz4 {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -723,7 +713,7 @@ fun! tar#Extract()
|
||||
let extractcmd= substitute(extractcmd,"-","-I lz4","")
|
||||
call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname))
|
||||
if v:shell_error != 0
|
||||
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.lz4 ".fname.": failed!" | echohl NONE
|
||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.lz4 {fname}: failed!")
|
||||
else
|
||||
echo "***note*** successfully extracted ".fname
|
||||
endif
|
||||
@@ -736,15 +726,50 @@ endfun
|
||||
" ---------------------------------------------------------------------
|
||||
" s:Rmdir: {{{2
|
||||
fun! s:Rmdir(fname)
|
||||
if has("unix")
|
||||
call system("/bin/rm -rf -- ".shellescape(a:fname,0))
|
||||
elseif has("win32") || has("win95") || has("win64") || has("win16")
|
||||
if &shell =~? "sh$"
|
||||
call system("/bin/rm -rf -- ".shellescape(a:fname,0))
|
||||
else
|
||||
call system("del /S ".shellescape(a:fname,0))
|
||||
endif
|
||||
call delete(a:fname, 'rf')
|
||||
endfun
|
||||
|
||||
" s:FileHeader: {{{2
|
||||
fun! s:Header(fname)
|
||||
let header= readblob(a:fname, 0, 6)
|
||||
" Nvim: see https://github.com/neovim/neovim/pull/34968
|
||||
if header[0:2] == 0z425A68 " bzip2 header
|
||||
return "bzip2"
|
||||
elseif header[0:2] == 0z425A33 " bzip3 header
|
||||
return "bzip3"
|
||||
elseif header == 0zFD377A58.5A00 " xz header
|
||||
return "xz"
|
||||
elseif header[0:3] == 0z28B52FFD " zstd header
|
||||
return "zstd"
|
||||
elseif header[0:3] == 0z04224D18 " lz4 header
|
||||
return "lz4"
|
||||
elseif (header[0:1] == 0z1F9D ||
|
||||
\ header[0:1] == 0z1F8B ||
|
||||
\ header[0:1] == 0z1F9E ||
|
||||
\ header[0:1] == 0z1FA0 ||
|
||||
\ header[0:1] == 0z1F1E)
|
||||
return "gzip"
|
||||
endif
|
||||
return "unknown"
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
" s:WinPath: {{{2
|
||||
fun! s:WinPath(path)
|
||||
if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && has("win32")
|
||||
" remove cygdrive prefix, if present
|
||||
let path = substitute(a:path, '/cygdrive/\(.\)', '\1:', '')
|
||||
" remove trailing slash (Win95)
|
||||
let path = substitute(path, '\(\\\|/\)$', '', 'g')
|
||||
" remove escaped spaces
|
||||
let path = substitute(path, '\ ', ' ', 'g')
|
||||
" convert slashes to backslashes
|
||||
let path = substitute(path, '/', '\', 'g')
|
||||
else
|
||||
let path = a:path
|
||||
endif
|
||||
|
||||
return path
|
||||
endfun
|
||||
|
||||
" =====================================================================
|
||||
|
@@ -77,49 +77,11 @@ function! tutor#TutorFolds()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Marks: {{{1
|
||||
|
||||
function! tutor#ApplyMarks()
|
||||
hi! link tutorExpect Special
|
||||
if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
|
||||
let b:tutor_sign_id = 1
|
||||
for expct in keys(b:tutor_metadata['expect'])
|
||||
let lnum = eval(expct)
|
||||
call matchaddpos('tutorExpect', [lnum])
|
||||
call tutor#CheckLine(lnum)
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! tutor#ApplyMarksOnChanged()
|
||||
if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
|
||||
let lnum = line('.')
|
||||
if index(keys(b:tutor_metadata['expect']), string(lnum)) > -1
|
||||
call tutor#CheckLine(lnum)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! tutor#CheckLine(line)
|
||||
if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
|
||||
let bufn = bufnr('%')
|
||||
let ctext = getline(a:line)
|
||||
let signs = sign_getplaced(bufn, {'lnum': a:line})[0].signs
|
||||
if !empty(signs)
|
||||
call sign_unplace('', {'id': signs[0].id})
|
||||
endif
|
||||
if b:tutor_metadata['expect'][string(a:line)] == -1 || ctext ==# b:tutor_metadata['expect'][string(a:line)]
|
||||
exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorok buffer=".bufn
|
||||
else
|
||||
exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorbad buffer=".bufn
|
||||
endif
|
||||
let b:tutor_sign_id+=1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Tutor Cmd: {{{1
|
||||
|
||||
function! s:Locale()
|
||||
" Make sure l:lang exists before returning.
|
||||
let l:lang = 'en_US'
|
||||
if exists('v:lang') && v:lang =~ '\a\a'
|
||||
let l:lang = v:lang
|
||||
elseif $LC_ALL =~ '\a\a'
|
||||
@@ -132,8 +94,6 @@ function! s:Locale()
|
||||
endif
|
||||
elseif $LANG =~ '\a\a'
|
||||
let l:lang = $LANG
|
||||
else
|
||||
let l:lang = 'en_US'
|
||||
endif
|
||||
return split(l:lang, '_')
|
||||
endfunction
|
||||
@@ -167,15 +127,21 @@ function! s:Sort(a, b)
|
||||
return retval
|
||||
endfunction
|
||||
|
||||
function! s:GlobTutorials(name)
|
||||
" returns a list of all tutor files matching the given name
|
||||
function! tutor#GlobTutorials(name, locale)
|
||||
let locale = a:locale
|
||||
" pack/*/start/* are not reported in &rtp
|
||||
let rtp = nvim_list_runtime_paths()
|
||||
\ ->map({_, v -> escape(v:lua.vim.fs.normalize(v), ',')})
|
||||
\ ->join(',')
|
||||
" search for tutorials:
|
||||
" 1. non-localized
|
||||
let l:tutors = s:GlobPath(&rtp, 'tutor/'.a:name.'.tutor')
|
||||
let l:tutors = s:GlobPath(rtp, 'tutor/'.a:name.'.tutor')
|
||||
" 2. localized for current locale
|
||||
let l:locale_tutors = s:GlobPath(&rtp, 'tutor/'.s:Locale()[0].'/'.a:name.'.tutor')
|
||||
let l:locale_tutors = s:GlobPath(rtp, 'tutor/'.locale.'/'.a:name.'.tutor')
|
||||
" 3. fallback to 'en'
|
||||
if len(l:locale_tutors) == 0
|
||||
let l:locale_tutors = s:GlobPath(&rtp, 'tutor/en/'.a:name.'.tutor')
|
||||
let l:locale_tutors = s:GlobPath(rtp, 'tutor/en/'.a:name.'.tutor')
|
||||
endif
|
||||
call extend(l:tutors, l:locale_tutors)
|
||||
return uniq(sort(l:tutors, 's:Sort'), 's:Sort')
|
||||
@@ -197,7 +163,7 @@ function! tutor#TutorCmd(tutor_name)
|
||||
let l:tutor_name = fnamemodify(l:tutor_name, ':r')
|
||||
endif
|
||||
|
||||
let l:tutors = s:GlobTutorials(l:tutor_name)
|
||||
let l:tutors = tutor#GlobTutorials(l:tutor_name, s:Locale()[0])
|
||||
|
||||
if len(l:tutors) == 0
|
||||
echom "No tutorial with that name found"
|
||||
@@ -220,15 +186,37 @@ function! tutor#TutorCmd(tutor_name)
|
||||
|
||||
call tutor#SetupVim()
|
||||
exe "edit ".l:to_open
|
||||
call tutor#EnableInteractive(v:true)
|
||||
call tutor#ApplyTransform()
|
||||
endfunction
|
||||
|
||||
function! tutor#TutorCmdComplete(lead,line,pos)
|
||||
let l:tutors = s:GlobTutorials('*')
|
||||
let l:tutors = tutor#GlobTutorials('*', s:Locale()[0])
|
||||
let l:names = uniq(sort(map(l:tutors, 'fnamemodify(v:val, ":t:r")'), 's:Sort'))
|
||||
return join(l:names, "\n")
|
||||
endfunction
|
||||
|
||||
" Enables/disables interactive mode.
|
||||
function! tutor#EnableInteractive(enable)
|
||||
let enable = a:enable
|
||||
if enable
|
||||
setlocal buftype=nofile
|
||||
setlocal concealcursor+=inv
|
||||
setlocal conceallevel=2
|
||||
lua require('nvim.tutor').apply_marks()
|
||||
augroup tutor_interactive
|
||||
autocmd! TextChanged,TextChangedI <buffer> lua require('nvim.tutor').apply_marks_on_changed()
|
||||
augroup END
|
||||
else
|
||||
setlocal buftype<
|
||||
setlocal concealcursor<
|
||||
setlocal conceallevel<
|
||||
if exists('#tutor_interactive')
|
||||
autocmd! tutor_interactive * <buffer>
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! tutor#ApplyTransform()
|
||||
if has('win32')
|
||||
sil! %s/{unix:(\(.\{-}\)),win:(\(.\{-}\))}/\2/g
|
||||
|
@@ -15,6 +15,7 @@
|
||||
" 2024 Aug 18 by Vim Project: correctly handle special globbing chars
|
||||
" 2024 Aug 21 by Vim Project: simplify condition to detect MS-Windows
|
||||
" 2025 Mar 11 by Vim Project: handle filenames with leading '-' correctly
|
||||
" 2025 Jul 12 by Vim Project: drop ../ on write to prevent path traversal attacks
|
||||
" License: Vim License (see vim's :help license)
|
||||
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
|
||||
" Permission is hereby granted to use and distribute this code,
|
||||
@@ -71,8 +72,9 @@ fun! s:Mess(group, msg)
|
||||
echohl Normal
|
||||
endfun
|
||||
|
||||
if v:version < 702
|
||||
call s:Mess('WarningMsg', "***warning*** this version of zip needs vim 7.2 or later")
|
||||
if !has('nvim-0.10') && v:version < 901
|
||||
" required for defer
|
||||
call s:Mess('WarningMsg', "***warning*** this version of zip needs vim 9.1 or later")
|
||||
finish
|
||||
endif
|
||||
" sanity checks
|
||||
@@ -235,59 +237,62 @@ endfun
|
||||
" zip#Write: {{{2
|
||||
fun! zip#Write(fname)
|
||||
let dict = s:SetSaneOpts()
|
||||
let need_rename = 0
|
||||
defer s:RestoreOpts(dict)
|
||||
|
||||
" sanity checks
|
||||
if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
|
||||
call s:Mess('Error', "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program")
|
||||
return
|
||||
endif
|
||||
if !exists("*mkdir")
|
||||
call s:Mess('Error', "***error*** (zip#Write) sorry, mkdir() doesn't work on your system")
|
||||
return
|
||||
call s:Mess('Error', "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program")
|
||||
return
|
||||
endif
|
||||
|
||||
let curdir= getcwd()
|
||||
let tmpdir= tempname()
|
||||
if tmpdir =~ '\.'
|
||||
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
||||
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
||||
endif
|
||||
call mkdir(tmpdir,"p")
|
||||
|
||||
" attempt to change to the indicated directory
|
||||
if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
|
||||
return
|
||||
return
|
||||
endif
|
||||
|
||||
" place temporary files under .../_ZIPVIM_/
|
||||
if isdirectory("_ZIPVIM_")
|
||||
call delete("_ZIPVIM_", "rf")
|
||||
call delete("_ZIPVIM_", "rf")
|
||||
endif
|
||||
call mkdir("_ZIPVIM_")
|
||||
cd _ZIPVIM_
|
||||
|
||||
if has("unix")
|
||||
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||
let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
|
||||
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||
let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
|
||||
else
|
||||
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
|
||||
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
|
||||
endif
|
||||
if fname =~ '^[.]\{1,2}/'
|
||||
call system(g:zip_zipcmd." -d ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
|
||||
let fname = fname->substitute('^\([.]\{1,2}/\)\+', '', 'g')
|
||||
let need_rename = 1
|
||||
endif
|
||||
|
||||
if fname =~ '/'
|
||||
let dirpath = substitute(fname,'/[^/]\+$','','e')
|
||||
if has("win32unix") && executable("cygpath")
|
||||
let dirpath = substitute(fname,'/[^/]\+$','','e')
|
||||
if has("win32unix") && executable("cygpath")
|
||||
let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
|
||||
endif
|
||||
call mkdir(dirpath,"p")
|
||||
endif
|
||||
call mkdir(dirpath,"p")
|
||||
endif
|
||||
if zipfile !~ '/'
|
||||
let zipfile= curdir.'/'.zipfile
|
||||
let zipfile= curdir.'/'.zipfile
|
||||
endif
|
||||
|
||||
exe "w! ".fnameescape(fname)
|
||||
" don't overwrite files forcefully
|
||||
exe "w ".fnameescape(fname)
|
||||
if has("win32unix") && executable("cygpath")
|
||||
let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
|
||||
let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
|
||||
endif
|
||||
|
||||
if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
|
||||
@@ -296,21 +301,24 @@ fun! zip#Write(fname)
|
||||
|
||||
call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
|
||||
if v:shell_error != 0
|
||||
call s:Mess('Error', "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname)
|
||||
call s:Mess('Error', "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname)
|
||||
|
||||
elseif s:zipfile_{winnr()} =~ '^\a\+://'
|
||||
" support writing zipfiles across a network
|
||||
let netzipfile= s:zipfile_{winnr()}
|
||||
1split|enew
|
||||
let binkeep= &binary
|
||||
let eikeep = &ei
|
||||
set binary ei=all
|
||||
exe "noswapfile e! ".fnameescape(zipfile)
|
||||
call netrw#NetWrite(netzipfile)
|
||||
let &ei = eikeep
|
||||
let &binary = binkeep
|
||||
q!
|
||||
unlet s:zipfile_{winnr()}
|
||||
" support writing zipfiles across a network
|
||||
let netzipfile= s:zipfile_{winnr()}
|
||||
1split|enew
|
||||
let binkeep= &binary
|
||||
let eikeep = &ei
|
||||
set binary ei=all
|
||||
exe "noswapfile e! ".fnameescape(zipfile)
|
||||
call netrw#NetWrite(netzipfile)
|
||||
let &ei = eikeep
|
||||
let &binary = binkeep
|
||||
q!
|
||||
unlet s:zipfile_{winnr()}
|
||||
elseif need_rename
|
||||
exe $"sil keepalt file {fnameescape($"zipfile://{zipfile}::{fname}")}"
|
||||
call s:Mess('Warning', "***error*** (zip#Browse) Path Traversal Attack detected, dropping relative path")
|
||||
endif
|
||||
|
||||
" cleanup and restore current directory
|
||||
@@ -319,7 +327,6 @@ fun! zip#Write(fname)
|
||||
call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
|
||||
call delete(tmpdir, "rf")
|
||||
setlocal nomod
|
||||
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
@@ -332,15 +339,18 @@ fun! zip#Extract()
|
||||
|
||||
" sanity check
|
||||
if fname =~ '^"'
|
||||
return
|
||||
return
|
||||
endif
|
||||
if fname =~ '/$'
|
||||
call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory")
|
||||
return
|
||||
call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory")
|
||||
return
|
||||
elseif fname =~ '^[.]\?[.]/'
|
||||
call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!")
|
||||
return
|
||||
endif
|
||||
if filereadable(fname)
|
||||
call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!")
|
||||
return
|
||||
call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!")
|
||||
return
|
||||
endif
|
||||
let target = fname->substitute('\[', '[[]', 'g')
|
||||
" unzip 6.0 does not support -- to denote end-of-arguments
|
||||
@@ -362,13 +372,12 @@ fun! zip#Extract()
|
||||
" extract the file mentioned under the cursor
|
||||
call system($"{g:zip_extractcmd} -o {shellescape(b:zipfile)} {target}")
|
||||
if v:shell_error != 0
|
||||
call s:Mess('Error', "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!")
|
||||
call s:Mess('Error', "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!")
|
||||
elseif !filereadable(fname)
|
||||
call s:Mess('Error', "***error*** attempted to extract ".fname." but it doesn't appear to be present!")
|
||||
call s:Mess('Error', "***error*** attempted to extract ".fname." but it doesn't appear to be present!")
|
||||
else
|
||||
echomsg "***note*** successfully extracted ".fname
|
||||
echomsg "***note*** successfully extracted ".fname
|
||||
endif
|
||||
|
||||
endfun
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
|
@@ -47,6 +47,7 @@ hi('WildMenu', { fg = 'Black', bg = 'Yellow', ctermfg = 'Black', cterm
|
||||
hi('VertSplit', { link = 'Normal' })
|
||||
hi('WinSeparator', { link = 'VertSplit' })
|
||||
hi('WinBarNC', { link = 'WinBar' })
|
||||
hi('DiffTextAdd', { link = 'DiffText' })
|
||||
hi('EndOfBuffer', { link = 'NonText' })
|
||||
hi('LineNrAbove', { link = 'LineNr' })
|
||||
hi('LineNrBelow', { link = 'LineNr' })
|
||||
@@ -61,6 +62,8 @@ hi('PmenuMatchSel', { link = 'PmenuSel' })
|
||||
hi('PmenuExtra', { link = 'Pmenu' })
|
||||
hi('PmenuExtraSel', { link = 'PmenuSel' })
|
||||
hi('ComplMatchIns', {})
|
||||
hi('ComplHint', { link = 'NonText' })
|
||||
hi('ComplHintMore', { link = 'MoreMsg' })
|
||||
hi('Substitute', { link = 'Search' })
|
||||
hi('Whitespace', { link = 'NonText' })
|
||||
hi('MsgSeparator', { link = 'StatusLine' })
|
||||
@@ -133,6 +136,7 @@ hi('DiagnosticDeprecated', { sp = 'Red', strikethrough = true, cterm =
|
||||
hi('DiagnosticUnnecessary', { link = 'Comment' })
|
||||
hi('LspInlayHint', { link = 'NonText' })
|
||||
hi('SnippetTabstop', { link = 'Visual' })
|
||||
hi('SnippetTabstopActive', { link = 'SnippetTabstop' })
|
||||
|
||||
-- Text
|
||||
hi('@markup.raw', { link = 'Comment' })
|
||||
|
25
runtime/compiler/gleam_build.vim
Normal file
25
runtime/compiler/gleam_build.vim
Normal file
@@ -0,0 +1,25 @@
|
||||
" Vim compiler file
|
||||
" Language: Gleam
|
||||
" Maintainer: Kirill Morozov <kirill@robotix.pro>
|
||||
" Based On: https://github.com/gleam-lang/gleam.vim
|
||||
" Last Change: 2025 Apr 21
|
||||
|
||||
if exists('current_compiler')
|
||||
finish
|
||||
endif
|
||||
let current_compiler = "gleam_build"
|
||||
|
||||
CompilerSet makeprg=gleam\ build
|
||||
|
||||
" Example error message:
|
||||
"
|
||||
" error: Unknown variable
|
||||
" ┌─ /home/michael/root/projects/tutorials/gleam/try/code/src/main.gleam:19:18
|
||||
" │
|
||||
" 19 │ Ok(tuple(name, spot))
|
||||
" │ ^^^^ did you mean `sport`?
|
||||
"
|
||||
" The name `spot` is not in scope here.
|
||||
CompilerSet errorformat=%Eerror:\ %m,%Wwarning:\ %m,%C\ %#┌─%#\ %f:%l:%c\ %#-%#
|
||||
|
||||
" vim: sw=2 sts=2 et
|
@@ -2,6 +2,7 @@
|
||||
" Compiler: Pandoc
|
||||
" Maintainer: Konfekt
|
||||
" Last Change: 2024 Nov 19
|
||||
" 2025 May 15 Update the title regex for CompilerSet #17321
|
||||
"
|
||||
" Expects output file extension, say `:make html` or `:make pdf`.
|
||||
" Passes additional arguments to pandoc, say `:make html --self-contained`.
|
||||
@@ -51,7 +52,7 @@ endfunction
|
||||
|
||||
execute 'CompilerSet makeprg=pandoc'..escape(
|
||||
\ ' --standalone'..
|
||||
\ (s:PandocFiletype(&filetype) ==# 'markdown' && (getline(1) =~# '^%\s\+\S\+' || (search('^title:\s+\S+', 'cnw') > 0)) ?
|
||||
\ (s:PandocFiletype(&filetype) ==# 'markdown' && (getline(1) =~# '^%\s\+\S\+' || (search('^title:\s\+\S\+', 'cnw') > 0)) ?
|
||||
\ '' : ' --metadata title=%:t:r:S')..
|
||||
\ ' '..s:PandocLang()..
|
||||
\ ' --from='..s:PandocFiletype(&filetype)..
|
||||
|
12
runtime/compiler/phpstan.vim
Normal file
12
runtime/compiler/phpstan.vim
Normal file
@@ -0,0 +1,12 @@
|
||||
" Vim compiler file
|
||||
" Compiler: PHPStan
|
||||
" Maintainer: Dietrich Moerman <dietrich.moerman@gmail.com>
|
||||
" Last Change: 2025 Jul 17
|
||||
|
||||
if exists("current_compiler")
|
||||
finish
|
||||
endif
|
||||
let current_compiler = "phpstan"
|
||||
|
||||
CompilerSet makeprg=composer\ exec\ --\ phpstan\ analyse\ -v\ --no-progress\ --error-format=raw
|
||||
CompilerSet errorformat=%f:%l:%m,%-G%.%#
|
@@ -1,10 +1,13 @@
|
||||
*ui.txt* Nvim
|
||||
*api-ui-events.txt* Nvim
|
||||
|
||||
|
||||
NVIM REFERENCE MANUAL
|
||||
|
||||
|
||||
Nvim UI protocol *UI* *ui*
|
||||
Nvim UI protocol *UI* *ui* *api-ui-events*
|
||||
|
||||
This document describes the UI protocol. See |gui| and |tui| for user-facing
|
||||
UI components and features.
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
@@ -226,8 +229,7 @@ the editor.
|
||||
sent from Nvim, like for |ui-cmdline|.
|
||||
|
||||
["chdir", path] ~
|
||||
The |current-directory| of the embedded Nvim process changed to
|
||||
`path`.
|
||||
The |current-directory| changed to `path`.
|
||||
|
||||
["mode_change", mode, mode_idx] ~
|
||||
Editor mode changed. The `mode` parameter is a string representing
|
||||
@@ -249,6 +251,14 @@ the editor.
|
||||
Indicates to the UI that it must stop rendering the cursor. This event
|
||||
is misnamed and does not actually have anything to do with busyness.
|
||||
|
||||
["restart", progpath, argv] ~
|
||||
|:restart| command has been used and the Nvim server is about to exit.
|
||||
The UI should wait for the server to exit, and then start a new server
|
||||
using `progpath` as the full path to the Nvim executable |v:progpath| and
|
||||
`argv` as its arguments |v:argv|, and reattach to the new server.
|
||||
Note: |--embed| and |--headless| are excluded from `argv`, and the client
|
||||
should decide itself whether to add either flag.
|
||||
|
||||
["suspend"] ~
|
||||
|:suspend| command or |CTRL-Z| mapping is used. A terminal client (or
|
||||
another client where it makes sense) could suspend itself. Other
|
||||
@@ -266,6 +276,10 @@ the editor.
|
||||
to an internal buffer, this is the time to display the redrawn parts
|
||||
to the user.
|
||||
|
||||
["ui_send", content] ~
|
||||
Write {content} to the connected TTY. Only UIs that have the
|
||||
"stdout_tty" |ui-option| set will receive this event.
|
||||
|
||||
==============================================================================
|
||||
Grid Events (line-based) *ui-linegrid*
|
||||
|
||||
@@ -609,12 +623,31 @@ tabs.
|
||||
size). If the window was previously hidden, it should now be shown
|
||||
again.
|
||||
|
||||
["win_float_pos", grid, win, anchor, anchor_grid, anchor_row, anchor_col, mouse_enabled, zindex] ~
|
||||
Display or reconfigure floating window `win`. The window should be
|
||||
displayed above another grid `anchor_grid` at the specified position
|
||||
`anchor_row` and `anchor_col`. For the meaning of `anchor` and more details
|
||||
of positioning, see |nvim_open_win()|. `mouse_enabled` is true if the
|
||||
window can receive mouse events.
|
||||
["win_float_pos", grid, win, anchor, anchor_grid, anchor_row, anchor_col, mouse_enabled, zindex, compindex, screen_row, screen_col] ~
|
||||
Display or reconfigure floating window `win`.
|
||||
|
||||
There are two alternative ways of positioning the window
|
||||
- Manually - The window should be displayed above another grid
|
||||
`anchor_grid` at the specified position `anchor_row` and
|
||||
`anchor_col`. For the meaning of `anchor` and more details of
|
||||
positioning, see |nvim_open_win()|. NOTE: you have to manually
|
||||
ensure that the window fits the screen, possibly by further
|
||||
reposition it. Ignore `screen_row` and `screen_col` in this case.
|
||||
- Let nvim take care of the positioning - You can ignore `anchor`
|
||||
and display the window at `screen_row` and `screen_col`.
|
||||
|
||||
`mouse_enabled` is true if the window can receive mouse events.
|
||||
|
||||
`zindex` is the configured zindex, while `compindex` is the exact
|
||||
rendering order of the windows determined by nvim. To render exactly
|
||||
like the TUI, first render all the non-floating windows, then render
|
||||
in the `compindex` order, overwriting any floating window cells.
|
||||
Finally, blend the floating window cells against the non-floating
|
||||
background. To add more blending, you can group the windows by zindex,
|
||||
and blend between the layers. But note that windows inside the same
|
||||
zindex should still overwrite previous cells inside the same layer
|
||||
without blending. This ensures that plugins that render multiple
|
||||
windows, to add borders for example, work as expected.
|
||||
|
||||
["win_external_pos", grid, win] ~
|
||||
Display or reconfigure external window `win`. The window should be
|
||||
@@ -627,7 +660,7 @@ tabs.
|
||||
["win_close", grid] ~
|
||||
Close the window.
|
||||
|
||||
["msg_set_pos", grid, row, scrolled, sep_char] ~
|
||||
["msg_set_pos", grid, row, scrolled, sep_char, zindex, compindex] ~
|
||||
Display messages on `grid`. The grid will be displayed at `row` on
|
||||
the default grid (grid=1), covering the full column width. `scrolled`
|
||||
indicates whether the message area has been scrolled to cover other
|
||||
@@ -638,6 +671,10 @@ tabs.
|
||||
When |ui-messages| is active, no message grid is used, and this event
|
||||
will not be sent.
|
||||
|
||||
`zindex` and `compindex` have the same meaning as for `win_float_pos`.
|
||||
The `zindex` always has a fixed value of 200 and included for
|
||||
completeness.
|
||||
|
||||
["win_viewport", grid, win, topline, botline, curline, curcol, line_count, scroll_delta] ~
|
||||
Indicates the range of buffer text displayed in the window, as well
|
||||
as the cursor position in the buffer. All positions are zero-based.
|
||||
@@ -719,8 +756,8 @@ This UI extension delegates presentation of the |cmdline| (except 'wildmenu').
|
||||
For command-line 'wildmenu' UI events, activate |ui-popupmenu|.
|
||||
|
||||
["cmdline_show", content, pos, firstc, prompt, indent, level, hl_id] ~
|
||||
content: List of [attrs, string]
|
||||
[[{}, "t"], [attrs, "est"], ...]
|
||||
content: List of [attrs, string, hl_id]
|
||||
[[{}, "t", hl_id], [attrs, "est", hl_id], ...]
|
||||
|
||||
Triggered when the cmdline is displayed or changed.
|
||||
The `content` is the full content that should be displayed in the
|
||||
@@ -752,9 +789,10 @@ For command-line 'wildmenu' UI events, activate |ui-popupmenu|.
|
||||
|
||||
Should be hidden at next cmdline_show.
|
||||
|
||||
["cmdline_hide", abort] ~
|
||||
Hide the cmdline. `abort` is true if the cmdline is hidden after an
|
||||
aborting condition (|c_Esc| or |c_CTRL-C|).
|
||||
["cmdline_hide", level, abort] ~
|
||||
Hide the cmdline. `level` is the nesting level of the cmdline being hidden.
|
||||
`abort` is true if the cmdline is hidden after an aborting condition
|
||||
(|c_Esc| or |c_CTRL-C|).
|
||||
|
||||
["cmdline_block_show", lines] ~
|
||||
Show a block of context to the current command line. For example if
|
||||
@@ -787,12 +825,15 @@ will be set to zero, but can be changed and used for the replacing cmdline or
|
||||
message window. Cmdline state is emitted as |ui-cmdline| events, which the UI
|
||||
must handle.
|
||||
|
||||
["msg_show", kind, content, replace_last, history] ~
|
||||
["msg_show", kind, content, replace_last, history, append, msg_id] ~
|
||||
Display a message to the user.
|
||||
|
||||
kind
|
||||
Name indicating the message kind:
|
||||
"" (empty) Unknown (consider a |feature-request|)
|
||||
"empty" Empty message (`:echo ""`), with empty `content`.
|
||||
Should clear messages sharing the 'cmdheight'
|
||||
area if it is the only message in a batch.
|
||||
"bufwrite" |:write| message
|
||||
"confirm" Message preceding a prompt (|:confirm|,
|
||||
|confirm()|, |inputlist()|, |z=|, …)
|
||||
@@ -804,11 +845,12 @@ must handle.
|
||||
"list_cmd" List output for various commands (|:ls|, |:set|, …)
|
||||
"lua_error" Error in |:lua| code
|
||||
"lua_print" |print()| from |:lua| code
|
||||
"progress" Progress message emitted by |nvim_echo()|
|
||||
"rpc_error" Error response from |rpcrequest()|
|
||||
"return_prompt" |press-enter| prompt after a multiple messages
|
||||
"quickfix" Quickfix navigation message
|
||||
"search_cmd" Entered search command
|
||||
"search_count" Search count message ("S" flag of 'shortmess')
|
||||
"shell_cmd" |:!cmd| executed command
|
||||
"shell_err" |:!cmd| shell stderr output
|
||||
"shell_out" |:!cmd| shell stdout output
|
||||
"shell_ret" |:!cmd| shell return code
|
||||
@@ -836,9 +878,24 @@ must handle.
|
||||
history
|
||||
True if the message was added to the |:messages| history.
|
||||
|
||||
append
|
||||
True if the message should be appeneded to the previous message,
|
||||
rather than started on a new line. Is set for |:echon|.
|
||||
|
||||
msg_id
|
||||
Unique identifier for the message. It can either be an integer or
|
||||
string. When message of same id appears it should replace the older message.
|
||||
|
||||
["msg_clear"] ~
|
||||
Clear all messages currently displayed by "msg_show". (Messages sent
|
||||
by other "msg_" events below will not be affected).
|
||||
Clear all messages currently displayed by "msg_show", emitted after
|
||||
clearing the screen (messages sent by other "msg_" events below should
|
||||
not be affected).
|
||||
|
||||
Guidance: The "clear messages" behavior is UI-specific. If the UI
|
||||
presents messages in a new window, it may choose to clear messages
|
||||
after a few seconds. If the UI presents messages in a persistent area
|
||||
(e.g. cmdline), it should clear messages at the start of the next
|
||||
batch (typically, the next event-loop cycle).
|
||||
|
||||
["msg_showmode", content] ~
|
||||
Shows 'showmode' and |recording| messages. `content` has the same
|
||||
@@ -854,12 +911,11 @@ must handle.
|
||||
statusline. `content` has the same format as in "msg_show". This event is
|
||||
sent with empty `content` to hide the last message.
|
||||
|
||||
["msg_history_show", entries] ~
|
||||
Sent when |:messages| command is invoked. History is sent as a list of
|
||||
entries, where each entry is a `[kind, content]` tuple.
|
||||
["msg_history_show", entries, prev_cmd] ~
|
||||
Sent when |:messages| or |g<| command is invoked. History is sent as a
|
||||
list of entries, where each entry is a `[kind, content, append]` tuple.
|
||||
|
||||
["msg_history_clear"] ~
|
||||
Clear the |:messages| history.
|
||||
prev_cmd
|
||||
True when sent with |g<| command, false with |:messages|.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
3290
runtime/doc/api.txt
3290
runtime/doc/api.txt
File diff suppressed because it is too large
Load Diff
@@ -73,11 +73,16 @@ Or use `:execute`: >
|
||||
Note that special characters (e.g., "%", "<cword>") in the ":autocmd"
|
||||
arguments are not expanded when the autocommand is defined. These will be
|
||||
expanded when the Event is recognized, and the {cmd} is executed. The only
|
||||
exception is that "<sfile>" is expanded when the autocmd is defined. Example:
|
||||
exception is that "<sfile>" (unlike "<script>") is expanded when the autocmd
|
||||
is defined. Example:
|
||||
>
|
||||
:au BufNewFile,BufRead *.html so <sfile>:h/html.vim
|
||||
|
||||
Here Vim expands <sfile> to the name of the file containing this line.
|
||||
However, <sfile> works differently in a function, in which case it's better to
|
||||
use `:execute` with <script> to achieve the same purpose:
|
||||
>
|
||||
:exe $'au BufNewFile,BufRead *.html so {expand("<script>:h")}/html.vim'
|
||||
|
||||
`:autocmd` adds to the list of autocommands regardless of whether they are
|
||||
already present. When your .vimrc file is sourced twice, the autocommands
|
||||
@@ -257,7 +262,7 @@ BufLeave Before leaving to another buffer. Also when
|
||||
Not used for ":qa" or ":q" when exiting Vim.
|
||||
*BufModifiedSet*
|
||||
BufModifiedSet After the `'modified'` value of a buffer has
|
||||
been changed.
|
||||
been changed. Special-case of |OptionSet|.
|
||||
*BufNew*
|
||||
BufNew After creating a new buffer (except during
|
||||
startup, see |VimEnter|) or renaming an
|
||||
@@ -301,6 +306,7 @@ BufUnload Before unloading a buffer, when the text in
|
||||
going to exit.
|
||||
NOTE: Current buffer "%" is not the target
|
||||
buffer "<afile>", "<abuf>". |<buffer=abuf>|
|
||||
*E1546*
|
||||
Do not switch buffers or windows!
|
||||
Not triggered when exiting and v:dying is 2 or
|
||||
more.
|
||||
@@ -344,7 +350,8 @@ BufWriteCmd Before writing the whole buffer to a file.
|
||||
The buffer contents should not be changed.
|
||||
When the command resets 'modified' the undo
|
||||
information is adjusted to mark older undo
|
||||
states as 'modified', like |:write| does.
|
||||
states as 'modified', like |:write| does. Use
|
||||
the |'[| and |']| marks for the range of lines.
|
||||
|Cmd-event|
|
||||
*BufWritePost*
|
||||
BufWritePost After writing the whole buffer to a file
|
||||
@@ -400,6 +407,16 @@ CmdlineLeave Before leaving the command-line (including
|
||||
Note: `abort` can only be changed from false
|
||||
to true: cannot execute an already aborted
|
||||
cmdline by changing it to false.
|
||||
*CmdlineLeavePre*
|
||||
CmdlineLeavePre Just before leaving the command line, and
|
||||
before |CmdlineLeave|. Useful for capturing
|
||||
completion info with |cmdcomplete_info()|, as
|
||||
this information is cleared before
|
||||
|CmdlineLeave| is triggered. Triggered for
|
||||
non-interactive use of ":" in a mapping, but
|
||||
not when using |<Cmd>|. Also triggered when
|
||||
abandoning the command line by typing CTRL-C
|
||||
or <Esc>. <afile> is set to |cmdline-char|.
|
||||
*CmdwinEnter*
|
||||
CmdwinEnter After entering the command-line window.
|
||||
Useful for setting options specifically for
|
||||
@@ -477,27 +494,16 @@ CompleteDone After Insert mode completion is done. Either
|
||||
- "accept": completion was
|
||||
accepted by |complete_CTRL-Y|.
|
||||
- "cancel": completion was
|
||||
stopped by |complete_CTRL-E.
|
||||
stopped by |complete_CTRL-E|.
|
||||
- "discard": completion was
|
||||
abandoned for other reason.
|
||||
|
||||
*CursorHold*
|
||||
CursorHold When the user doesn't press a key for the time
|
||||
specified with 'updatetime'. Not triggered
|
||||
until the user has pressed a key (i.e. doesn't
|
||||
fire every 'updatetime' ms if you leave Vim to
|
||||
make some coffee. :) See |CursorHold-example|
|
||||
for previewing tags.
|
||||
This event is only triggered in Normal mode.
|
||||
It is not triggered when waiting for a command
|
||||
argument to be typed, or a movement after an
|
||||
operator.
|
||||
While recording the CursorHold event is not
|
||||
triggered. |q|
|
||||
*<CursorHold>*
|
||||
Internally the autocommand is triggered by the
|
||||
<CursorHold> key. In an expression mapping
|
||||
|getchar()| may see this character.
|
||||
CursorHold When there is no user input for 'updatetime'
|
||||
duration, in Normal-mode. Not triggered while
|
||||
waiting for a command argument or movement
|
||||
after an operator, nor while |recording|
|
||||
a macro. See |CursorHold-example|.
|
||||
|
||||
Note: Interactive commands cannot be used for
|
||||
this event. There is no hit-enter prompt,
|
||||
@@ -648,14 +654,14 @@ FileType When the 'filetype' option has been set. The
|
||||
FileWriteCmd Before writing to a file, when not writing the
|
||||
whole buffer. Should do the writing to the
|
||||
file. Should not change the buffer. Use the
|
||||
'[ and '] marks for the range of lines.
|
||||
|'[| and |']| marks for the range of lines.
|
||||
|Cmd-event|
|
||||
*FileWritePost*
|
||||
FileWritePost After writing to a file, when not writing the
|
||||
whole buffer.
|
||||
*FileWritePre*
|
||||
FileWritePre Before writing to a file, when not writing the
|
||||
whole buffer. Use the '[ and '] marks for the
|
||||
whole buffer. Use the |'[| and |']| marks for the
|
||||
range of lines.
|
||||
*FilterReadPost*
|
||||
FilterReadPost After reading a file from a filter command.
|
||||
@@ -782,6 +788,31 @@ ModeChanged After changing the mode. The pattern is
|
||||
:au ModeChanged [vV\x16]*:* let &l:rnu = mode() =~# '^[vV\x16]'
|
||||
:au ModeChanged *:[vV\x16]* let &l:rnu = mode() =~# '^[vV\x16]'
|
||||
:au WinEnter,WinLeave * let &l:rnu = mode() =~# '^[vV\x16]'
|
||||
Progress *Progress*
|
||||
After a progress message is created or updated via
|
||||
`nvim_echo`. The pattern is matched against
|
||||
title of the message. The |event-data| contains:
|
||||
id: id of the message
|
||||
text: text of the message
|
||||
title: title of the progress message
|
||||
status: status of the progress message
|
||||
percent: how much progress has been
|
||||
made for this progress item
|
||||
Usage example:
|
||||
>
|
||||
vim.api.nvim_create_autocmd('Progress', {
|
||||
pattern={"term"},
|
||||
callback = function(ev)
|
||||
print(string.format('event fired: %s', vim.inspect(ev)))
|
||||
end
|
||||
})
|
||||
local id = vim.api.nvim_echo({{'searching...'}}, true,
|
||||
{kind='progress', status='running', percent=10, title="term"})
|
||||
vim.api.nvim_echo({{'searching'}}, true,
|
||||
{id = id, kind='progress', status='running', percent=50, title="term"})
|
||||
vim.api.nvim_echo({{'done'}}, true,
|
||||
{id = id, kind='progress', status='success', percent=100, title="term"})
|
||||
|
||||
< *OptionSet*
|
||||
OptionSet After setting an option (except during
|
||||
|startup|). The |autocmd-pattern| is matched
|
||||
@@ -822,6 +853,10 @@ OptionSet After setting an option (except during
|
||||
always use |:noautocmd| to prevent triggering
|
||||
OptionSet.
|
||||
|
||||
Note: Not triggered by the 'modified' option;
|
||||
the |BufModifiedSet| event may be used to
|
||||
handle that.
|
||||
|
||||
Non-recursive: |:set| in the autocommand does
|
||||
not trigger OptionSet again.
|
||||
|
||||
@@ -1034,7 +1069,7 @@ TermRequest When a |:terminal| child process emits an OSC,
|
||||
autocommand defined without |autocmd-nested|.
|
||||
|
||||
*TermResponse*
|
||||
TermResponse When Nvim receives an OSC or DCS response from
|
||||
TermResponse When Nvim receives a DA1, OSC, DCS, or APC response from
|
||||
the host terminal. Sets |v:termresponse|. The
|
||||
|event-data| is a table with the following fields:
|
||||
|
||||
@@ -1058,7 +1093,7 @@ TermResponse When Nvim receives an OSC or DCS response from
|
||||
local r, g, b = resp:match("\027%]4;1;rgb:(%w+)/(%w+)/(%w+)")
|
||||
end,
|
||||
})
|
||||
io.stdout:write("\027]4;1;?\027\\")
|
||||
vim.api.nvim_ui_send("\027]4;1;?\027\\")
|
||||
<
|
||||
*TextChanged*
|
||||
TextChanged After a change was made to the text in the
|
||||
@@ -1186,6 +1221,13 @@ WinScrolled After any window in the current tab page
|
||||
or changed width or height. See
|
||||
|win-scrolled-resized|.
|
||||
|
||||
Note: This can not be skipped with
|
||||
`:noautocmd`, because it triggers after
|
||||
processing normal commands when Vim is back in
|
||||
the main loop. If you want to disable this,
|
||||
consider setting the 'eventignore' option
|
||||
instead.
|
||||
|
||||
The pattern is matched against the |window-ID|
|
||||
of the first window that scrolled or resized.
|
||||
Both <amatch> and <afile> are set to the
|
||||
|
@@ -22,13 +22,13 @@ For inserting text see |insert.txt|.
|
||||
"dl".
|
||||
The <Del> key does not take a [count]. Instead, it
|
||||
deletes the last character of the count.
|
||||
See |'whichwrap'| for deleting a line break (join
|
||||
See 'whichwrap' for deleting a line break (join
|
||||
lines).
|
||||
|
||||
*X* *dh*
|
||||
["x]X Delete [count] characters before the cursor [into
|
||||
register x] (not |linewise|). Does the same as "dh".
|
||||
Also see |'whichwrap'|.
|
||||
Also see 'whichwrap'.
|
||||
|
||||
*d*
|
||||
["x]d{motion} Delete text that {motion} moves over [into register
|
||||
@@ -141,8 +141,8 @@ the 'joinspaces' option is on, these commands insert two spaces after a '.',
|
||||
The 'B' and 'M' flags in 'formatoptions' change the behavior for inserting
|
||||
spaces before and after a multibyte character |fo-table|.
|
||||
|
||||
The '[ mark is set at the end of the first line that was joined, '] at the end
|
||||
of the resulting line.
|
||||
The |'[| mark is set at the end of the first line that was joined, |']| at the
|
||||
end of the resulting line.
|
||||
|
||||
|
||||
==============================================================================
|
||||
@@ -367,7 +367,7 @@ CTRL-A Add [count] to the number or alphabetic character at
|
||||
*v_g_CTRL-A*
|
||||
{Visual}g CTRL-A Add [count] to the number or alphabetic character in
|
||||
the highlighted text. If several lines are
|
||||
highlighted, each one will be incremented by an
|
||||
highlighted, each one will be incremented by an
|
||||
additional [count] (so effectively creating a
|
||||
[count] incrementing sequence).
|
||||
For Example, if you have this list of numbers:
|
||||
@@ -583,9 +583,9 @@ with ".". Vim does not recognize a comment (starting with '"') after the
|
||||
={motion} Filter {motion} lines through the external program
|
||||
given with the 'equalprg' option. When the 'equalprg'
|
||||
option is empty (this is the default), use the
|
||||
internal formatting function |C-indenting| and
|
||||
|'lisp'|. But when 'indentexpr' is not empty, it will
|
||||
be used instead |indent-expression|.
|
||||
internal formatting function |C-indenting| and 'lisp'.
|
||||
But when 'indentexpr' is not empty, it will be used
|
||||
instead |indent-expression|.
|
||||
|
||||
*==*
|
||||
== Filter [count] lines like with ={motion}.
|
||||
@@ -644,8 +644,9 @@ original user.
|
||||
Repeat last :substitute with same search pattern and
|
||||
substitute string, but without the same flags. You
|
||||
may add [flags], see |:s_flags|.
|
||||
Note that after `:substitute` the '&' flag can't be
|
||||
used, it's recognized as a pattern separator.
|
||||
Note that after `:substitute` the '&' and '#' flags
|
||||
can't be used, they're recognized as a pattern
|
||||
separator.
|
||||
The space between `:substitute` and the 'c', 'g',
|
||||
'i', 'I' and 'r' flags isn't required, but in scripts
|
||||
it's a good idea to keep it to avoid confusion.
|
||||
@@ -948,22 +949,26 @@ This replaces each 'E' character with a euro sign. Read more in |<Char->|.
|
||||
|
||||
4.3 Changing tabs *change-tabs*
|
||||
*:ret* *:retab* *:retab!*
|
||||
:[range]ret[ab][!] [new_tabstop]
|
||||
:[range]ret[ab][!] [-indentonly] [{new-tabstop}]
|
||||
Replace all sequences of white-space containing a
|
||||
<Tab> with new strings of white-space using the new
|
||||
tabstop value given. If you do not specify a new
|
||||
tabstop size or it is zero, Vim uses the current value
|
||||
of 'tabstop'.
|
||||
<Tab> with new strings of white-space using
|
||||
{new-tabstop}. If you do not specify {new-tabstop} or
|
||||
it is zero, Vim uses the current value of 'tabstop'.
|
||||
The current value of 'tabstop' is always used to
|
||||
compute the width of existing tabs.
|
||||
With !, Vim also replaces strings of only normal
|
||||
spaces with tabs where appropriate.
|
||||
With 'expandtab' on, Vim replaces all tabs with the
|
||||
appropriate number of spaces.
|
||||
This command sets 'tabstop' to the new value given,
|
||||
and if performed on the whole file, which is default,
|
||||
should not make any visible change.
|
||||
Careful: This command modifies any <Tab> characters
|
||||
This command sets 'tabstop' to {new-tabstop} and if
|
||||
performed on the whole file, which is default, should
|
||||
not make any visible change.
|
||||
|
||||
When [-indentonly] is specified, only the leading
|
||||
white-space will be targeted. Any other consecutive
|
||||
white-space will not be changed.
|
||||
|
||||
Warning: This command modifies any <Tab> characters
|
||||
inside of strings in a C program. Use "\t" to avoid
|
||||
this (that's a good habit anyway).
|
||||
`:retab!` may also change a sequence of spaces by
|
||||
@@ -1105,6 +1110,11 @@ inside of strings can change! Also see 'softtabstop' option. >
|
||||
:[line]pu[t]! [x] Put the text [from register x] before [line] (default
|
||||
current line).
|
||||
|
||||
*:ip* *:iput*
|
||||
:[line]ip[ut] [x] like |:put|, but adjust indent to the current line
|
||||
|
||||
:[line]ip[ut]! [x] like |:put|!, but adjust indent to the current line
|
||||
|
||||
["x]]p or *]p* *]<MiddleMouse>*
|
||||
["x]]<MiddleMouse> Like "p", but adjust the indent to the current line.
|
||||
Using the mouse only works when 'mouse' contains 'n'
|
||||
@@ -1139,8 +1149,8 @@ the ":put" command, Vim always inserts the text in the next line. You can
|
||||
exchange two characters with the command sequence "xp". You can exchange two
|
||||
lines with the command sequence "ddp". You can exchange two words with the
|
||||
command sequence "deep" (start with the cursor in the blank space before the
|
||||
first word). You can use the "']" or "`]" command after the put command to
|
||||
move the cursor to the end of the inserted text, or use "'[" or "`[" to move
|
||||
first word). You can use the |']| or |`]| command after the put command to
|
||||
move the cursor to the end of the inserted text, or use |'[| or |`[| to move
|
||||
the cursor to the start.
|
||||
|
||||
*put-Visual-mode* *v_p* *v_P*
|
||||
@@ -1239,6 +1249,18 @@ mapped. E.g. |%| is mapped by the matchit plugin.
|
||||
With each successive deletion or change, Vim shifts the previous contents
|
||||
of register 1 into register 2, 2 into 3, and so forth, losing the previous
|
||||
contents of register 9.
|
||||
*yankring*
|
||||
To also store yanks (not only deletions) in registers 1-9, try this: >lua
|
||||
-- Yank-ring: store yanked text in registers 1-9.
|
||||
vim.api.nvim_create_autocmd('TextYankPost', {
|
||||
callback = function()
|
||||
if vim.v.event.operator == 'y' then
|
||||
for i = 9, 1, -1 do -- Shift all numbered registers.
|
||||
vim.fn.setreg(tostring(i), vim.fn.getreg(tostring(i - 1)))
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
3. Small delete register "- *quote_-* *quote-*
|
||||
This register contains text from commands that delete less than one line,
|
||||
@@ -1714,7 +1736,7 @@ B When joining lines, don't insert a space between two multibyte
|
||||
j Where it makes sense, remove a comment leader when joining lines. For
|
||||
example, joining:
|
||||
int i; // the index ~
|
||||
// in the list ~
|
||||
// in the list ~
|
||||
Becomes:
|
||||
int i; // the index in the list ~
|
||||
*fo-p*
|
||||
@@ -1817,6 +1839,7 @@ And a few warnings:
|
||||
|
||||
Vim has a sorting function and a sorting command. The sorting function can be
|
||||
found here: |sort()|, |uniq()|.
|
||||
Also see |:uniq|.
|
||||
|
||||
*:sor* *:sort*
|
||||
:[range]sor[t][!] [b][f][i][l][n][o][r][u][x] [/{pattern}/]
|
||||
@@ -1826,7 +1849,7 @@ found here: |sort()|, |uniq()|.
|
||||
With [!] the order is reversed.
|
||||
|
||||
With [i] case is ignored.
|
||||
|
||||
*:sort-l*
|
||||
With [l] sort uses the current collation locale.
|
||||
Implementation details: strcoll() is used to compare
|
||||
strings. See |:language| to check or set the collation
|
||||
@@ -1858,13 +1881,14 @@ found here: |sort()|, |uniq()|.
|
||||
|
||||
With [b] sorting is done on the first binary number in
|
||||
the line (after or inside a {pattern} match).
|
||||
|
||||
*:sort-u* *:sort-uniq*
|
||||
With [u] (u stands for unique) only keep the first of
|
||||
a sequence of identical lines (ignoring case when [i]
|
||||
is used). Without this flag, a sequence of identical
|
||||
lines will be kept in their original order.
|
||||
Note that leading and trailing white space may cause
|
||||
lines to be different.
|
||||
When you just want to make things unique, use |:uniq|.
|
||||
|
||||
When /{pattern}/ is specified and there is no [r] flag
|
||||
the text matched with {pattern} is skipped, so that
|
||||
@@ -1911,4 +1935,55 @@ The sorting can be interrupted, but if you interrupt it too late in the
|
||||
process you may end up with duplicated lines. This also depends on the system
|
||||
library function used.
|
||||
|
||||
==============================================================================
|
||||
8. Deduplicating text *deduplicating* *unique*
|
||||
|
||||
Vim has a deduplicating function and a deduplicating command. The
|
||||
deduplicating function can be found here: |uniq()|.
|
||||
Also see |:sort-uniq|.
|
||||
|
||||
*:uni* *:uniq*
|
||||
:[range]uni[q][!] [i][l][r][u] [/{pattern}/]
|
||||
Remove duplicate lines that are adjacent to each other
|
||||
in [range]. When no range is given, all lines are
|
||||
processed.
|
||||
|
||||
With [i] case is ignored when comparing lines.
|
||||
|
||||
With [l] comparison uses the current collation locale.
|
||||
See |:sort-l| for more details.
|
||||
|
||||
With [r] comparison is done on the text that matches
|
||||
/{pattern}/ instead of the full line.
|
||||
|
||||
With [u] only keep lines that do not repeat (i.e., are
|
||||
not immediately followed by the same line).
|
||||
|
||||
With [!] only keep lines that are immediately followed
|
||||
by a duplicate.
|
||||
|
||||
If both [!] and [u] are given, [u] is ignored and [!]
|
||||
takes effect.
|
||||
|
||||
When /{pattern}/ is specified and [r] is not used, the
|
||||
text matched with {pattern} is skipped and comparison
|
||||
is done on what comes after the match.
|
||||
'ignorecase' applies to the pattern, but 'smartcase'
|
||||
is not used.
|
||||
Instead of the slash any non-letter can be used.
|
||||
|
||||
For example, to remove adjacent duplicate lines based
|
||||
on the second comma-separated field: >
|
||||
:uniq /[^,]*,/
|
||||
< Or to keep only unique lines ignoring the first 5
|
||||
characters: >
|
||||
:uniq u /.\{5}/
|
||||
< If {pattern} is empty (e.g. // is used), the last
|
||||
search pattern is used.
|
||||
|
||||
Note that leading and trailing white space may cause
|
||||
lines to be considered different.
|
||||
To remove all duplicates regardless of position, use
|
||||
|:sort-u| or external tools.
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -177,84 +177,85 @@ Put this in `uppercase.vim` and run: >bash
|
||||
==============================================================================
|
||||
5. Using a prompt buffer *prompt-buffer*
|
||||
|
||||
If you want to type input for the job in a Vim window you have a few options:
|
||||
- Use a normal buffer and handle all possible commands yourself.
|
||||
This will be complicated, since there are so many possible commands.
|
||||
- Use a terminal window. This works well if what you type goes directly to
|
||||
the job and the job output is directly displayed in the window.
|
||||
See |terminal|.
|
||||
- Use a window with a prompt buffer. This works well when entering a line for
|
||||
the job in Vim while displaying (possibly filtered) output from the job.
|
||||
Prompt buffers provide a "prompt" interface: they are like regular buffers,
|
||||
except only the last section of the buffer is editable, and the user can
|
||||
"submit" the prompt by hitting Enter. Useful for implementing:
|
||||
|
||||
- chat UI
|
||||
- REPL or shell plugins
|
||||
- advanced "picker" plugins
|
||||
|
||||
A prompt buffer is created by setting 'buftype' to "prompt". You would
|
||||
normally only do that in a newly created buffer.
|
||||
normally only do that in a newly created buffer: >vim
|
||||
|
||||
The user can edit and enter one line of text at the very last line of the
|
||||
buffer. When pressing Enter in the prompt line the callback set with
|
||||
|prompt_setcallback()| is invoked. It would normally send the line to a job.
|
||||
Another callback would receive the output from the job and display it in the
|
||||
buffer, below the prompt (and above the next prompt).
|
||||
:set buftype=prompt
|
||||
|
||||
Only the text in the last line, after the prompt, is editable. The rest of the
|
||||
buffer is not modifiable with Normal mode commands. It can be modified by
|
||||
calling functions, such as |append()|. Using other commands may mess up the
|
||||
buffer.
|
||||
The user can edit and enter text at the end of the buffer. Pressing Enter in
|
||||
the prompt section invokes the |prompt_setcallback()| callback, which is
|
||||
typically expected to process the prompt and show results by appending to the
|
||||
buffer. To input multiline text, use Shift+Enter to add a new line without
|
||||
submitting the prompt, or just |put| or |paste| multiline text.
|
||||
|
||||
After setting 'buftype' to "prompt" Vim does not automatically start Insert
|
||||
mode, use `:startinsert` if you want to enter Insert mode, so that the user
|
||||
can start typing a line.
|
||||
Only the "prompt" part of the buffer user-editable, given by the |':| mark.
|
||||
The rest of the buffer is not modifiable with Normal mode commands, though it
|
||||
can be modified by functions such as |append()|. Using other commands may
|
||||
mess up the buffer.
|
||||
|
||||
The text of the prompt can be set with the |prompt_setprompt()| function. If
|
||||
no prompt is set with |prompt_setprompt()|, "% " is used. You can get the
|
||||
effective prompt text for a buffer, with |prompt_getprompt()|.
|
||||
After setting `buftype=prompt`:
|
||||
- Nvim unsets the 'comments' option.
|
||||
- Nvim does not automatically start Insert mode (use `:startinsert` if you
|
||||
want to enter Insert mode)
|
||||
|
||||
The prompt prefix defaults to "% ", but can be set with |prompt_setprompt()|.
|
||||
You can get the effective prompt prefix for with |prompt_getprompt()|.
|
||||
|
||||
The user can go to Normal mode and navigate through the buffer. This can be
|
||||
useful to see older output or copy text.
|
||||
|
||||
The CTRL-W key can be used to start a window command, such as CTRL-W w to
|
||||
switch to the next window. This also works in Insert mode (use Shift-CTRL-W
|
||||
to delete a word). When leaving the window Insert mode will be stopped. When
|
||||
coming back to the prompt window Insert mode will be restored.
|
||||
By default during prompt insert-mode, the CTRL-W key can be used to start
|
||||
a window command, such as CTRL-W w to switch to the next window. (Use
|
||||
Shift-CTRL-W to delete a word). When leaving the window Insert mode will be
|
||||
stopped. When coming back to the prompt window Insert mode will be restored.
|
||||
|
||||
Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
|
||||
the cursor to the last line. "A" will move to the end of the line, "I" to the
|
||||
start of the line.
|
||||
|
||||
Here is an example for Unix. It starts a shell in the background and prompts
|
||||
for the next shell command. Output from the shell is displayed above the
|
||||
prompt. >vim
|
||||
Example: start a shell in the background and prompt for the next shell
|
||||
command, displaying shell output above the prompt: >vim
|
||||
|
||||
" Function handling a line of text that has been typed.
|
||||
func TextEntered(text)
|
||||
" Send the text to a shell with Enter appended.
|
||||
call chansend(g:shell_job, [a:text, ''])
|
||||
endfunc
|
||||
" Handles a line of user input.
|
||||
func OnSubmit(text)
|
||||
" Send the text to a shell with Enter appended.
|
||||
call chansend(g:shell_job, [a:text, ''])
|
||||
endfunc
|
||||
|
||||
" Function handling output from the shell: Add it above the prompt.
|
||||
func GotOutput(channel, msg, name)
|
||||
call append(line("$") - 1, a:msg)
|
||||
endfunc
|
||||
" Handles output from the shell.
|
||||
func OnOutput(channel, msg, name)
|
||||
" Add shell output above the prompt.
|
||||
call append(line('$') - 1, a:msg)
|
||||
endfunc
|
||||
|
||||
" Function handling the shell exits: close the window.
|
||||
func JobExit(job, status, event)
|
||||
quit!
|
||||
endfunc
|
||||
" Handles the shell exit.
|
||||
func JobExit(job, status, event)
|
||||
quit!
|
||||
endfunc
|
||||
|
||||
" Start a shell in the background.
|
||||
let shell_job = jobstart(["/bin/sh"], #{
|
||||
\ on_stdout: function('GotOutput'),
|
||||
\ on_stderr: function('GotOutput'),
|
||||
\ on_exit: function('JobExit'),
|
||||
\ })
|
||||
" Start a shell in the background.
|
||||
let shell_job = jobstart(['/bin/sh'], #{
|
||||
\ on_stdout: function('OnOutput'),
|
||||
\ on_stderr: function('OnOutput'),
|
||||
\ on_exit: function('JobExit'),
|
||||
\ })
|
||||
|
||||
new
|
||||
set buftype=prompt
|
||||
let buf = bufnr('')
|
||||
call prompt_setcallback(buf, function("TextEntered"))
|
||||
call prompt_setprompt(buf, "shell command: ")
|
||||
new
|
||||
set buftype=prompt
|
||||
let buf = bufnr('')
|
||||
call prompt_setcallback(buf, function('OnSubmit'))
|
||||
call prompt_setprompt(buf, 'shell command: ')
|
||||
|
||||
" start accepting shell commands
|
||||
startinsert
|
||||
" Start accepting shell commands.
|
||||
startinsert
|
||||
<
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
vim:tw=78:ts=8:et:sw=4:ft=help:norl:
|
||||
|
@@ -388,7 +388,7 @@ CTRL-D List names that match the pattern in front of the cursor.
|
||||
to the end.
|
||||
The 'wildoptions' option can be set to "tagfile" to list the
|
||||
file of matching tags.
|
||||
*c_CTRL-I* *c_wildchar* *c_<Tab>*
|
||||
*c_CTRL-I* *c_wildchar* *c_<Tab>* */_<Tab>*
|
||||
'wildchar' option
|
||||
A match is done on the pattern in front of the cursor. The
|
||||
match (if there are several, the first match) is inserted
|
||||
@@ -398,6 +398,10 @@ CTRL-D List names that match the pattern in front of the cursor.
|
||||
again and there were multiple matches, the next
|
||||
match is inserted. After the last match, the first is used
|
||||
again (wrap around).
|
||||
|
||||
In search context use <CTRL-V><Tab> or "\t" to search for a
|
||||
literal <Tab> instead of triggering completion.
|
||||
|
||||
The behavior can be changed with the 'wildmode' option.
|
||||
*c_<S-Tab>*
|
||||
<S-Tab> Like 'wildchar' or <Tab>, but begin with the last match and
|
||||
@@ -430,7 +434,7 @@ CTRL-G When 'incsearch' is set, entering a search pattern for "/" or
|
||||
"?" and the current match is displayed then CTRL-G will move
|
||||
to the next match (does not take |search-offset| into account)
|
||||
Use CTRL-T to move to the previous match. Hint: on a regular
|
||||
keyboard T is above G.
|
||||
keyboard G is below T.
|
||||
*c_CTRL-T* */_CTRL-T*
|
||||
CTRL-T When 'incsearch' is set, entering a search pattern for "/" or
|
||||
"?" and the current match is displayed then CTRL-T will move
|
||||
@@ -447,6 +451,8 @@ When repeating 'wildchar' or CTRL-N you cycle through the matches, eventually
|
||||
ending up back to what was typed. If the first match is not what you wanted,
|
||||
you can use <S-Tab> or CTRL-P to go straight back to what you typed.
|
||||
|
||||
See also |wildtrigger()|.
|
||||
|
||||
The 'wildmenu' option can be set to show the matches just above the command
|
||||
line.
|
||||
|
||||
@@ -564,7 +570,6 @@ that see the '"' as part of their argument:
|
||||
:menu (and the like)
|
||||
:mkspell
|
||||
:normal
|
||||
:ownsyntax
|
||||
:popup
|
||||
:registers
|
||||
:return
|
||||
@@ -862,7 +867,7 @@ to insert special things while typing you can use the CTRL-R command. For
|
||||
example, "%" stands for the current file name, while CTRL-R % inserts the
|
||||
current file name right away. See |c_CTRL-R|.
|
||||
|
||||
Note: If you want to avoid the effects of special characters in a Vim script
|
||||
Note: If you want to avoid the effects of special characters in a Vim script
|
||||
you may want to use |fnameescape()|. Also see |`=|.
|
||||
|
||||
|
||||
@@ -937,14 +942,6 @@ Note: these are typed literally, they are not special keys!
|
||||
events).
|
||||
When the match is with a file name, it is expanded to the
|
||||
full path.
|
||||
*:<sfile>* *<sfile>*
|
||||
<sfile> When executing a `:source` command, is replaced with the
|
||||
file name of the sourced file. *E498*
|
||||
When executing a function, is replaced with the call stack,
|
||||
as with <stack> (this is for backwards compatibility, using
|
||||
<stack> or <script> is preferred).
|
||||
Note that filename-modifiers are useless when <sfile> is
|
||||
not used inside a script.
|
||||
*:<stack>* *<stack>*
|
||||
<stack> is replaced with the call stack, using
|
||||
"function {function-name}[{lnum}]" for a function line
|
||||
@@ -952,7 +949,7 @@ Note: these are typed literally, they are not special keys!
|
||||
".." in between items. E.g.:
|
||||
"function {function-name1}[{lnum}]..{function-name2}[{lnum}]"
|
||||
If there is no call stack you get error *E489* .
|
||||
*:<script>* *<script>*
|
||||
*:<script>* *<script>* *E498*
|
||||
<script> When executing a `:source` command, is replaced with the file
|
||||
name of the sourced file. When executing a function, is
|
||||
replaced with the file name of the script where it is
|
||||
@@ -971,7 +968,7 @@ Note: these are typed literally, they are not special keys!
|
||||
*filename-modifiers*
|
||||
*:_%:* *::8* *::p* *::.* *::~* *::h* *::t* *::r* *::e* *::s* *::gs* *::S*
|
||||
*%:8* *%:p* *%:.* *%:~* *%:h* *%:t* *%:r* *%:e* *%:s* *%:gs* *%:S*
|
||||
The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<sfile>",
|
||||
The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<script>",
|
||||
"<afile>" or "<abuf>". They are also used with the |fnamemodify()| function.
|
||||
These modifiers can be given, in this order:
|
||||
:p Make file name a full path. Must be the first modifier. Also
|
||||
@@ -1242,8 +1239,10 @@ Example: >
|
||||
:au CmdwinLeave : let &cpt = b:cpt_save
|
||||
This sets 'complete' to use completion in the current window for |i_CTRL-N|.
|
||||
Another example: >
|
||||
:au CmdwinEnter [/?] startinsert
|
||||
:au CmdwinEnter [/\?] startinsert
|
||||
This will make Vim start in Insert mode in the command-line window.
|
||||
Note: The "?" needs to be escaped, as this is a |file-pattern|. See also
|
||||
|cmdline-autocompletion|.
|
||||
|
||||
*cmdline-char* *cmdwin-char*
|
||||
The character used for the pattern indicates the type of command-line:
|
||||
|
@@ -160,5 +160,4 @@ In WinDbg: choose Open Crash Dump on the File menu. Follow the instructions in
|
||||
Visual Studio 2017 Community Edition can be downloaded for free from:
|
||||
https://visualstudio.microsoft.com/downloads/
|
||||
|
||||
=========================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -12,6 +12,42 @@ They should not be used in new scripts, and old scripts should be updated.
|
||||
==============================================================================
|
||||
Deprecated features
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
DEPRECATED IN 0.12 *deprecated-0.12*
|
||||
|
||||
API
|
||||
|
||||
• todo
|
||||
|
||||
DIAGNOSTICS
|
||||
|
||||
• "float" in |vim.diagnostic.JumpOpts|. Use "on_jump" instead.
|
||||
• "float" in |vim.diagnostic.Opts.Jump|. Use "on_jump" instead.
|
||||
|
||||
HIGHLIGHTS
|
||||
|
||||
• *:ownsyntax* *w:current_syntax* Use 'winhighlight' instead.
|
||||
|
||||
LSP
|
||||
|
||||
• *vim.lsp.client_is_stopped()* Use |vim.lsp.get_client_by_id()| instead.
|
||||
• *vim.lsp.util.stylize_markdown()* Use |vim.treesitter.start()| with
|
||||
`vim.wo.conceallevel = 2`.
|
||||
• *vim.lsp.log.should_log()* Use |vim.lsp.log.set_format_func()| instead
|
||||
and return `nil` to omit entries from the logfile.
|
||||
• *vim.lsp.semantic_tokens.start()* Use `vim.lsp.semantic_tokens.enable(true)` instead
|
||||
• *vim.lsp.semantic_tokens.stop()* Use `vim.lsp.semantic_tokens.enable(false)` instead
|
||||
• *vim.lsp.set_log_level()* Use `vim.lsp.log.set_level()` instead
|
||||
• *vim.lsp.get_log_path()* Use `vim.lsp.log.get_filename()` instead
|
||||
|
||||
LUA
|
||||
|
||||
• *vim.diff()* Renamed to |vim.text.diff()|
|
||||
|
||||
VIMSCRIPT
|
||||
|
||||
• todo
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
DEPRECATED IN 0.11 *deprecated-0.11*
|
||||
|
||||
@@ -66,7 +102,7 @@ LUA
|
||||
• vim.validate(opts: table) Use form 1. See |vim.validate()|.
|
||||
|
||||
VIMSCRIPT
|
||||
• *termopen()* Use |jobstart() with `{term: v:true}`.
|
||||
• *termopen()* Use |jobstart()| with `{term: v:true}`.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
DEPRECATED IN 0.10 *deprecated-0.10*
|
||||
@@ -298,13 +334,12 @@ UI EXTENSIONS
|
||||
• *term_background* Unused. The terminal background color is now detected
|
||||
by the Nvim core directly instead of the TUI.
|
||||
|
||||
VARIABLES
|
||||
VIMSCRIPT
|
||||
• *<sfile>* Use |<script>| or |<stack>| instead.
|
||||
• *b:terminal_job_pid* Use `jobpid(&channel)` instead.
|
||||
• *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
|
||||
• Lua: `vim.bo[bufnr].channel`
|
||||
• Vimscript: `getbufvar(bufnr, '&channel')`
|
||||
|
||||
VIMSCRIPT
|
||||
• *buffer_exists()* Obsolete name for |bufexists()|.
|
||||
• *buffer_name()* Obsolete name for |bufname()|.
|
||||
• *buffer_number()* Obsolete name for |bufnr()|.
|
||||
|
@@ -53,6 +53,27 @@ Other references:
|
||||
- https://github.com/neovim/neovim/pull/21605
|
||||
|
||||
|
||||
==============================================================================
|
||||
API
|
||||
|
||||
*dev-api-fast*
|
||||
API functions and Vimscript "eval" functions may be marked as |api-fast| which
|
||||
means they are safe to call in Lua callbacks and other scenarios. A functions
|
||||
CANNOT be marked as "fast" if could trigger `os_breakcheck()`, which may
|
||||
"yield" the current execution and start a new execution of code not expecting
|
||||
this:
|
||||
- accidentally recursing into a function not expecting this.
|
||||
- changing (global) state without restoring it before returning to the
|
||||
"yielded" callsite.
|
||||
|
||||
In practice, this means any code that could trigger `os_breakcheck()` cannot
|
||||
be "fast". For example, commit 3940c435e405 fixed such a bug with
|
||||
`nvim__get_runtime` by explicitly disallowing `os_breakcheck()` via the
|
||||
`EW_NOBREAK` flag.
|
||||
|
||||
Common examples of non-fast code: regexp matching, wildcard expansion,
|
||||
expression evaluation.
|
||||
|
||||
|
||||
==============================================================================
|
||||
|
||||
|
@@ -255,8 +255,7 @@ functions. >c
|
||||
|
||||
Integration with declarations generator ~
|
||||
|
||||
Every C file must contain #include of the generated header file, guarded by
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS.
|
||||
Every C file must contain #include of the generated header file.
|
||||
|
||||
Include must go after other #includes and typedefs in .c files and after
|
||||
everything else in header files. It is allowed to omit #include in a .c file
|
||||
@@ -272,9 +271,7 @@ contain only non-static function declarations. >c
|
||||
|
||||
typedef int FooType;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "foo.c.generated.h"
|
||||
#endif
|
||||
#include "foo.c.generated.h"
|
||||
|
||||
…
|
||||
|
||||
@@ -284,9 +281,7 @@ contain only non-static function declarations. >c
|
||||
|
||||
…
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "foo.h.generated.h"
|
||||
#endif
|
||||
#include "foo.h.generated.h"
|
||||
|
||||
|
||||
64-bit Portability ~
|
||||
@@ -901,8 +896,8 @@ Return Values ~
|
||||
|
||||
Do not needlessly surround the `return` expression with parentheses.
|
||||
|
||||
Use parentheses in `return expr`; only where you would use them in `x =
|
||||
expr;`. >c
|
||||
Use parentheses in `return expr;` only where you would also use them in
|
||||
`x = expr;`. >c
|
||||
|
||||
return result;
|
||||
return (some_long_condition && another_condition);
|
||||
|
@@ -171,8 +171,8 @@ USING GDBSERVER IN TMUX
|
||||
Consider using a custom makefile
|
||||
https://github.com/neovim/neovim/blob/master/BUILD.md#custom-makefile to
|
||||
quickly start debugging sessions using the `gdbserver` method mentioned above.
|
||||
This example `local.mk` will create the debugging session when you type `make
|
||||
debug`.
|
||||
This example `local.mk` will create the debugging session when you type
|
||||
`make debug`.
|
||||
>make
|
||||
.PHONY: dbg-start dbg-attach debug build
|
||||
|
||||
|
@@ -311,7 +311,7 @@ Nvim's filetype detection behavior matches Vim, but is implemented as part of
|
||||
|vim.filetype| (see `$VIMRUNTIME/lua/vim/filetype.lua`). The logic is encoded in
|
||||
three tables, listed in order of precedence (the first match is returned):
|
||||
1. `filename` for literal full path or basename lookup;
|
||||
2. `pattern` for matching filenames or paths against |lua-patterns|, optimized
|
||||
2. `pattern` for matching filenames or paths against |lua-pattern|s, optimized
|
||||
for fast lookup;
|
||||
3. `extension` for literal extension lookup.
|
||||
|
||||
|
@@ -201,7 +201,7 @@ Docstring format:
|
||||
- Markdown is supported.
|
||||
- Tags are written as `[tag]()`.
|
||||
- References are written as `[tag]`
|
||||
- Use ``` for code samples.
|
||||
- Use "```" for code samples.
|
||||
Code samples can be annotated as `vim` or `lua`
|
||||
|
||||
Example: the help for |nvim_open_win()| is generated from a docstring defined
|
||||
@@ -245,7 +245,7 @@ Docstring format:
|
||||
- Markdown is supported.
|
||||
- Tags are written as `[tag]()`.
|
||||
- References are written as `[tag]`
|
||||
- Use ``` for code samples.
|
||||
- Use "```" for code samples.
|
||||
Code samples can be annotated as `vim` or `lua`
|
||||
- Use `@since <api-level>` to note the |api-level| when the function became
|
||||
"stable". If `<api-level>` is greater than the current stable release (or
|
||||
@@ -353,7 +353,7 @@ Where possible, these patterns apply to _both_ Lua and the API:
|
||||
- Examples: |vim.lsp.codelens.clear()| |vim.diagnostic.enable()|
|
||||
- Any function signature that accepts a callback (example: |table.foreach()|)
|
||||
should place it as the LAST parameter (after opts), if possible (or ALWAYS
|
||||
for "continuation callbacks"—functions called exactly once).
|
||||
for |continuation|s——functions called exactly once).
|
||||
- Improves readability by placing the less "noisy" arguments near the start.
|
||||
- Consistent with luv.
|
||||
- Useful for future async lib which transforms functions of the form
|
||||
@@ -426,6 +426,9 @@ Use existing common {verb} names (actions) if possible:
|
||||
- add: Appends or inserts into a collection
|
||||
- attach: Listens to something to get events from it (TODO: rename to "on"?)
|
||||
- call: Calls a function
|
||||
- callback |continuation|: Function parameter (NOT a field) that
|
||||
returns the result of an async function. Use the "on_…"
|
||||
naming-convention for all other callbacks and event handlers.
|
||||
- cancel: Cancels or dismisses an event or interaction, typically
|
||||
user-initiated and without error. (Compare "abort", which
|
||||
cancels and signals error/failure.)
|
||||
@@ -441,8 +444,11 @@ Use existing common {verb} names (actions) if possible:
|
||||
- get: Gets things. Two variants (overloads):
|
||||
1. `get<T>(id: int): T` returns one item.
|
||||
2. `get<T>(filter: dict): T[]` returns a list.
|
||||
- has: Checks for the presence of an item, feature, etc.
|
||||
- inspect: Presents a high-level, often interactive, view
|
||||
- is_enabled: Checks if functionality is enabled.
|
||||
- on_…: Handles events or async results, or registers such
|
||||
a handler. |dev-name-events|
|
||||
- open: Opens something (a buffer, window, …)
|
||||
- parse: Parses something into a structured form
|
||||
- set: Sets a thing (or group of things)
|
||||
@@ -452,6 +458,7 @@ Use existing common {verb} names (actions) if possible:
|
||||
- try_{verb}: Best-effort operation, failure returns null or error obj
|
||||
|
||||
Do NOT use these deprecated verbs:
|
||||
- contains: Prefer "has".
|
||||
- disable: Prefer `enable(enable: boolean)`.
|
||||
- exit: Prefer "cancel" (or "stop" if appropriate).
|
||||
- is_disabled: Prefer `is_enabled()`.
|
||||
@@ -475,7 +482,6 @@ everywhere, not "buffer" in some places and "buf" in others.
|
||||
|
||||
Do NOT use these deprecated nouns:
|
||||
- buffer Use "buf" instead
|
||||
- callback Use on_foo instead
|
||||
- command Use "cmd" instead
|
||||
- window Use "win" instead
|
||||
|
||||
@@ -493,6 +499,14 @@ Use this format to name API (RPC) events: >
|
||||
Example: >
|
||||
nvim_buf_changedtick_event
|
||||
<
|
||||
*continuation*
|
||||
A "continuation" is implemented as a callback function that returns the result
|
||||
of an async function and is called exactly once. Often accepts `err` as the
|
||||
first parameter, to avoid erroring on the main thread. Example: >
|
||||
foo(…, callback: fun(err, …))
|
||||
Use the name `callback` only for a continuation. All other callbacks and event
|
||||
handlers should be named with the |dev-name-events| "on_…" convention.
|
||||
|
||||
*dev-api-name*
|
||||
Use this format to name new RPC |API| functions: >
|
||||
nvim_{topic}_{verb}_{arbitrary-qualifiers}
|
||||
@@ -666,6 +680,8 @@ External UIs are expected to implement these common features:
|
||||
the user).
|
||||
- Support the text decorations/attributes given by |ui-event-hl_attr_define|.
|
||||
The "url" attr should be presented as a clickable hyperlink.
|
||||
- Handle the "restart" UI event so that |:restart| works.
|
||||
- Detect capslock and show an indicator if capslock is active.
|
||||
|
||||
|
||||
vim:tw=78:ts=8:sw=4:et:ft=help:norl:
|
||||
|
@@ -69,6 +69,16 @@ Functions that take a severity as an optional parameter (e.g.
|
||||
<
|
||||
This form allows users to filter for specific severities
|
||||
|
||||
==============================================================================
|
||||
DEFAULTS *diagnostic-defaults*
|
||||
|
||||
These diagnostic keymaps are created unconditionally when Nvim starts:
|
||||
- `]d` jumps to the next diagnostic in the buffer. |]d-default|
|
||||
- `[d` jumps to the previous diagnostic in the buffer. |[d-default|
|
||||
- `]D` jumps to the last diagnostic in the buffer. |]D-default|
|
||||
- `[D` jumps to the first diagnostic in the buffer. |[D-default|
|
||||
- `<C-w>d` shows diagnostic at cursor in a floating window. |CTRL-W_d-default|
|
||||
|
||||
==============================================================================
|
||||
HANDLERS *diagnostic-handlers*
|
||||
|
||||
@@ -180,6 +190,28 @@ the `virtual_lines` handler with the following keymap: >lua
|
||||
end, { desc = 'Toggle diagnostic virtual_lines' })
|
||||
<
|
||||
|
||||
*diagnostic-on-jump-example*
|
||||
You can use the `on_jump` option from |vim.diagnostic.jump()| to show the
|
||||
diagnostic that was jumped to using a specific handler. For example, the
|
||||
following uses the `virtual_lines` handler when jumping to a diagnostic: >lua
|
||||
|
||||
local virt_lines_ns = vim.api.nvim_create_namespace 'on_diagnostic_jump'
|
||||
|
||||
--- @param diagnostic? vim.Diagnostic
|
||||
--- @param bufnr integer
|
||||
local function on_jump(diagnostic, bufnr)
|
||||
if not diagnostic then return end
|
||||
|
||||
vim.diagnostic.show(
|
||||
virt_lines_ns,
|
||||
bufnr,
|
||||
{ diagnostic },
|
||||
{ virtual_lines = { current_line = true }, virtual_text = false }
|
||||
)
|
||||
end
|
||||
|
||||
vim.diagnostic.config({ jump = { on_jump = on_jump } })
|
||||
<
|
||||
*diagnostic-loclist-example*
|
||||
Whenever the |location-list| is opened, the following `show` handler will show
|
||||
the most recent diagnostics: >lua
|
||||
@@ -269,6 +301,26 @@ DiagnosticVirtualTextHint
|
||||
DiagnosticVirtualTextOk
|
||||
Used for "Ok" diagnostic virtual text.
|
||||
|
||||
*hl-DiagnosticVirtualLinesError*
|
||||
DiagnosticVirtualLinesError
|
||||
Used for "Error" diagnostic virtual lines.
|
||||
|
||||
*hl-DiagnosticVirtualLinesWarn*
|
||||
DiagnosticVirtualLinesWarn
|
||||
Used for "Warn" diagnostic virtual lines.
|
||||
|
||||
*hl-DiagnosticVirtualLinesInfo*
|
||||
DiagnosticVirtualLinesInfo
|
||||
Used for "Info" diagnostic virtual lines.
|
||||
|
||||
*hl-DiagnosticVirtualLinesHint*
|
||||
DiagnosticVirtualLinesHint
|
||||
Used for "Hint" diagnostic virtual lines.
|
||||
|
||||
*hl-DiagnosticVirtualLinesOk*
|
||||
DiagnosticVirtualLinesOk
|
||||
Used for "Ok" diagnostic virtual lines.
|
||||
|
||||
*hl-DiagnosticUnderlineError*
|
||||
DiagnosticUnderlineError
|
||||
Used to underline "Error" diagnostics.
|
||||
@@ -388,27 +440,43 @@ Example: >lua
|
||||
Lua module: vim.diagnostic *diagnostic-api*
|
||||
|
||||
*vim.Diagnostic*
|
||||
Extends: |vim.Diagnostic.Set|
|
||||
|
||||
*diagnostic-structure*
|
||||
|
||||
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
|
||||
0-based rows and columns). |api-indexing|
|
||||
|
||||
Fields: ~
|
||||
• {bufnr}? (`integer`) Buffer number
|
||||
• {lnum} (`integer`) The starting line of the diagnostic
|
||||
(0-indexed)
|
||||
• {end_lnum}? (`integer`) The final line of the diagnostic (0-indexed)
|
||||
• {bufnr} (`integer`) Buffer number
|
||||
• {end_lnum} (`integer`) The final line of the diagnostic (0-indexed)
|
||||
• {col} (`integer`) The starting column of the diagnostic
|
||||
(0-indexed)
|
||||
• {end_col}? (`integer`) The final column of the diagnostic
|
||||
• {end_col} (`integer`) The final column of the diagnostic
|
||||
(0-indexed)
|
||||
• {severity}? (`vim.diagnostic.Severity`) The severity of the
|
||||
• {severity} (`vim.diagnostic.Severity`) The severity of the
|
||||
diagnostic |vim.diagnostic.severity|
|
||||
• {namespace}? (`integer`)
|
||||
|
||||
*vim.Diagnostic.Set*
|
||||
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
|
||||
0-based rows and columns). |api-indexing|
|
||||
|
||||
Fields: ~
|
||||
• {lnum} (`integer`) The starting line of the diagnostic
|
||||
(0-indexed)
|
||||
• {col}? (`integer`, default: `0`) The starting column of the
|
||||
diagnostic (0-indexed)
|
||||
• {end_lnum}? (`integer`, default: `lnum`) The final line of the
|
||||
diagnostic (0-indexed)
|
||||
• {end_col}? (`integer`, default: `col`) The final column of the
|
||||
diagnostic (0-indexed)
|
||||
• {severity}? (`vim.diagnostic.Severity`, default: `vim.diagnostic.severity.ERROR`)
|
||||
The severity of the diagnostic |vim.diagnostic.severity|
|
||||
• {message} (`string`) The diagnostic text
|
||||
• {source}? (`string`) The source of the diagnostic
|
||||
• {code}? (`string|integer`) The diagnostic code
|
||||
• {user_data}? (`any`) arbitrary data plugins can add
|
||||
• {namespace}? (`integer`)
|
||||
|
||||
*vim.diagnostic.GetOpts*
|
||||
A table with the following keys:
|
||||
@@ -420,6 +488,9 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
specified line number.
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||
|diagnostic-severity|.
|
||||
• {enabled}? (`boolean`, default: `nil`) Limit diagnostics to only
|
||||
enabled or disabled. If nil, enablement is ignored. See
|
||||
|vim.diagnostic.enable()|
|
||||
|
||||
*vim.diagnostic.JumpOpts*
|
||||
Extends: |vim.diagnostic.GetOpts|
|
||||
@@ -445,13 +516,9 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
file or not. Similar to 'wrapscan'.
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||
|diagnostic-severity|.
|
||||
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default: `false`)
|
||||
If `true`, call |vim.diagnostic.open_float()| after
|
||||
moving. If a table, pass the table as the {opts}
|
||||
parameter to |vim.diagnostic.open_float()|. Unless
|
||||
overridden, the float will show diagnostics at the new
|
||||
cursor position (as if "cursor" were passed to the
|
||||
"scope" option).
|
||||
• {on_jump}? (`fun(diagnostic:vim.Diagnostic?, bufnr:integer)`)
|
||||
Optional callback invoked with the diagnostic that was
|
||||
jumped to.
|
||||
• {winid}? (`integer`, default: `0`) Window ID
|
||||
|
||||
*vim.diagnostic.NS*
|
||||
@@ -505,7 +572,8 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
Fields: ~
|
||||
• {bufnr}? (`integer`, default: current buffer) Buffer number
|
||||
to show diagnostics from.
|
||||
• {namespace}? (`integer`) Limit diagnostics to the given namespace
|
||||
• {namespace}? (`integer|integer[]`) Limit diagnostics to the given
|
||||
namespace(s).
|
||||
• {scope}? (`'line'|'buffer'|'cursor'|'c'|'l'|'b'`, default:
|
||||
`line`) Show diagnostics from the whole buffer
|
||||
(`buffer"`, the current cursor line (`line`), or the
|
||||
@@ -563,8 +631,8 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
*vim.diagnostic.Opts.Jump*
|
||||
|
||||
Fields: ~
|
||||
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default: false)
|
||||
Default value of the {float} parameter of
|
||||
• {on_jump}? (`fun(diagnostic:vim.Diagnostic?, bufnr:integer)`)
|
||||
Default value of the {on_jump} parameter of
|
||||
|vim.diagnostic.jump()|.
|
||||
• {wrap}? (`boolean`, default: true) Default value of the {wrap}
|
||||
parameter of |vim.diagnostic.jump()|.
|
||||
@@ -574,8 +642,8 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
*vim.diagnostic.Opts.Signs*
|
||||
|
||||
Fields: ~
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show virtual text
|
||||
for diagnostics matching the given severity
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show signs for
|
||||
diagnostics matching the given severity
|
||||
|diagnostic-severity|
|
||||
• {priority}? (`integer`, default: `10`) Base priority to use for
|
||||
signs. When {severity_sort} is used, the priority of a
|
||||
@@ -607,6 +675,9 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
*vim.diagnostic.Opts.VirtualLines*
|
||||
|
||||
Fields: ~
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show virtual
|
||||
lines for diagnostics matching the given severity
|
||||
|diagnostic-severity|
|
||||
• {current_line}? (`boolean`, default: `false`) Only show diagnostics
|
||||
for the current line.
|
||||
• {format}? (`fun(diagnostic:vim.Diagnostic): string?`) A
|
||||
@@ -621,8 +692,12 @@ Lua module: vim.diagnostic *diagnostic-api*
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show
|
||||
virtual text for diagnostics matching the given
|
||||
severity |diagnostic-severity|
|
||||
• {current_line}? (`boolean`) Only show diagnostics for the
|
||||
current line. (default `false`)
|
||||
• {current_line}? (`boolean`) Show or hide diagnostics based on
|
||||
the current cursor line. If `true`, only
|
||||
diagnostics on the current cursor line are
|
||||
shown. If `false`, all diagnostics are shown
|
||||
except on the current cursor line. If `nil`, all
|
||||
diagnostics are shown. (default `nil`)
|
||||
• {source}? (`boolean|"if_many"`) Include the diagnostic
|
||||
source in virtual text. Use `'if_many'` to only
|
||||
show sources if there is more than one
|
||||
@@ -881,7 +956,7 @@ set({namespace}, {bufnr}, {diagnostics}, {opts}) *vim.diagnostic.set()*
|
||||
Parameters: ~
|
||||
• {namespace} (`integer`) The diagnostic namespace
|
||||
• {bufnr} (`integer`) Buffer number
|
||||
• {diagnostics} (`vim.Diagnostic[]`) See |vim.Diagnostic|.
|
||||
• {diagnostics} (`vim.Diagnostic.Set[]`) See |vim.Diagnostic.Set|.
|
||||
• {opts} (`vim.diagnostic.Opts?`) Display options to pass to
|
||||
|vim.diagnostic.show()|. See |vim.diagnostic.Opts|.
|
||||
|
||||
@@ -890,8 +965,8 @@ setloclist({opts}) *vim.diagnostic.setloclist()*
|
||||
|
||||
Parameters: ~
|
||||
• {opts} (`table?`) Configuration table with the following keys:
|
||||
• {namespace}? (`integer`) Only add diagnostics from the given
|
||||
namespace.
|
||||
• {namespace}? (`integer[]|integer`) Only add diagnostics from
|
||||
the given namespace(s).
|
||||
• {winnr}? (`integer`, default: `0`) Window number to set
|
||||
location list for.
|
||||
• {open}? (`boolean`, default: `true`) Open the location list
|
||||
@@ -900,14 +975,19 @@ setloclist({opts}) *vim.diagnostic.setloclist()*
|
||||
"Diagnostics".
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||
|diagnostic-severity|.
|
||||
• {format}? (`fun(diagnostic:vim.Diagnostic): string?`) A
|
||||
function that takes a diagnostic as input and returns a
|
||||
string or nil. If the return value is nil, the diagnostic is
|
||||
not displayed in the location list. Else the output text is
|
||||
used to display the diagnostic.
|
||||
|
||||
setqflist({opts}) *vim.diagnostic.setqflist()*
|
||||
Add all diagnostics to the quickfix list.
|
||||
|
||||
Parameters: ~
|
||||
• {opts} (`table?`) Configuration table with the following keys:
|
||||
• {namespace}? (`integer`) Only add diagnostics from the given
|
||||
namespace.
|
||||
• {namespace}? (`integer[]|integer`) Only add diagnostics from
|
||||
the given namespace(s).
|
||||
• {open}? (`boolean`, default: `true`) Open quickfix list
|
||||
after setting.
|
||||
• {title}? (`string`) Title of quickfix list. Defaults to
|
||||
@@ -915,6 +995,11 @@ setqflist({opts}) *vim.diagnostic.setqflist()*
|
||||
title, it's updated. If not, a new quickfix list is created.
|
||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||
|diagnostic-severity|.
|
||||
• {format}? (`fun(diagnostic:vim.Diagnostic): string?`) A
|
||||
function that takes a diagnostic as input and returns a
|
||||
string or nil. If the return value is nil, the diagnostic is
|
||||
not displayed in the quickfix list. Else the output text is
|
||||
used to display the diagnostic.
|
||||
|
||||
*vim.diagnostic.show()*
|
||||
show({namespace}, {bufnr}, {diagnostics}, {opts})
|
||||
@@ -934,6 +1019,23 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
|
||||
• {opts} (`vim.diagnostic.Opts?`) Display options. See
|
||||
|vim.diagnostic.Opts|.
|
||||
|
||||
status({bufnr}) *vim.diagnostic.status()*
|
||||
Returns formatted string with diagnostics for the current buffer. The
|
||||
severities with 0 diagnostics are left out. Example `E:2 W:3 I:4 H:5`
|
||||
|
||||
To customise appearance, set diagnostic signs text with >lua
|
||||
vim.diagnostic.config({
|
||||
signs = { text = { [vim.diagnostic.severity.ERROR] = 'e', ... } }
|
||||
})
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {bufnr} (`integer?`) Buffer number to get diagnostics from. Defaults
|
||||
to 0 for the current buffer
|
||||
|
||||
Return: ~
|
||||
(`string`)
|
||||
|
||||
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
|
||||
Convert a list of diagnostics to a list of quickfix items that can be
|
||||
passed to |setqflist()| or |setloclist()|.
|
||||
|
@@ -214,14 +214,28 @@ The diffs are highlighted with these groups:
|
||||
|hl-DiffAdd| DiffAdd Added (inserted) lines. These lines exist in
|
||||
this buffer but not in another.
|
||||
|hl-DiffChange| DiffChange Changed lines.
|
||||
|hl-DiffText| DiffText Changed text inside a Changed line. Vim
|
||||
finds the first character that is different,
|
||||
and the last character that is different
|
||||
(searching from the end of the line). The
|
||||
text in between is highlighted. This means
|
||||
that parts in the middle that are still the
|
||||
same are highlighted anyway. The 'diffopt'
|
||||
flags "iwhite" and "icase" are used here.
|
||||
|hl-DiffText| DiffText Changed text inside a Changed line. Exact
|
||||
behavior depends on the `inline:` setting in
|
||||
'diffopt'.
|
||||
With `inline:` set to "simple", Vim finds the
|
||||
first character that is different, and the
|
||||
last character that is different (searching
|
||||
from the end of the line). The text in
|
||||
between is highlighted. This means that parts
|
||||
in the middle that are still the same are
|
||||
highlighted anyway. The 'diffopt' flags
|
||||
"iwhite" and "icase" are used here.
|
||||
With `inline:` set to "char" or "word", Vim
|
||||
uses the internal diff library to perform a
|
||||
detailed diff between the changed blocks and
|
||||
highlight the exact difference between the
|
||||
two. Will respect any 'diffopt' flag that
|
||||
affects internal diff.
|
||||
Not used when `inline:` is set to "none".
|
||||
|hl-DiffTextAdd| DiffTextAdd Added text inside a Changed line. Similar to
|
||||
DiffText, but used when there is no
|
||||
corresponding text in other buffers. Not used
|
||||
when `inline:` is set to "simple" or "none".
|
||||
|hl-DiffDelete| DiffDelete Deleted lines. Also called filler lines,
|
||||
because they don't really exist in this
|
||||
buffer.
|
||||
@@ -278,18 +292,20 @@ that the buffers will be equal within the specified range.
|
||||
|
||||
|
||||
When no [range] is given, the diff at the cursor position or just above it is
|
||||
affected. When [range] is used, Vim tries to only put or get the specified
|
||||
lines. When there are deleted lines, this may not always be possible.
|
||||
affected. There can be deleted lines below the last line of the buffer. When
|
||||
the cursor is on the last line in the buffer and there is no diff above this
|
||||
line, and no [range] is given, the diff below the cursor position will be used
|
||||
instead.
|
||||
|
||||
There can be deleted lines below the last line of the buffer. When the cursor
|
||||
is on the last line in the buffer and there is no diff above this line, the
|
||||
":diffget" and "do" commands will obtain lines from the other buffer.
|
||||
When [range] is used, Vim tries to only put or get the specified lines. When
|
||||
there are deleted lines, they will be used if they are between the lines
|
||||
specified by [range].
|
||||
|
||||
To be able to get those lines from another buffer in a [range] it's allowed to
|
||||
use the last line number plus one. This command gets all diffs from the other
|
||||
buffer: >
|
||||
To be able to put or get those lines to/from another buffer in a [range] it's
|
||||
allowed to use 0 and the last line number plus one. This command gets all
|
||||
diffs from the other buffer: >
|
||||
|
||||
:1,$+1diffget
|
||||
:0,$+1diffget
|
||||
|
||||
Note that deleted lines are displayed, but not counted as text lines. You
|
||||
can't move the cursor into them. To fill the deleted lines with the lines
|
||||
@@ -308,9 +324,131 @@ name or a part of a buffer name. Examples:
|
||||
diff mode (e.g., "file.c.v2")
|
||||
|
||||
==============================================================================
|
||||
5. Diff options *diff-options*
|
||||
5. Diff anchors *diff-anchors*
|
||||
|
||||
Also see |'diffopt'| and the "diff" item of |'fillchars'|.
|
||||
Diff anchors allow you to control where the diff algorithm aligns and
|
||||
synchronize text across files. Each anchor matches each other in each file,
|
||||
allowing you to control the output of a diff.
|
||||
|
||||
This is useful when a change involves complicated edits. For example, if a
|
||||
function was moved to another location and further edited. By default, the
|
||||
algorithm aims to create the smallest diff, which results in that entire
|
||||
function being considered to be deleted and added on the other side, making it
|
||||
hard to see what the actual edit on it was. You can use diff anchors to pin
|
||||
that function so the diff algorithm will align based on it.
|
||||
|
||||
To use it, set anchors using 'diffanchors' which is a comma-separated list of
|
||||
{address} in each file, and then add "anchor" to 'diffopt'. Internaly, Vim
|
||||
splits each file up into sections split by the anchors. It performs the diff
|
||||
on each pair of sections separately before merging the results back.
|
||||
|
||||
Setting 'diffanchors' will update the diff immediately. If an anchor is tied
|
||||
to a mark, and you change what the mark is pointed to, you need to manually
|
||||
call |:diffupdate| afterwards to get the updated diff results.
|
||||
|
||||
Example:
|
||||
|
||||
Let's say we have the following files, side-by-side. We are interested in the
|
||||
change that happened to the function `foo()`, which was both edited and moved.
|
||||
|
||||
File A: >
|
||||
int foo() {
|
||||
int n = 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
int g = 1;
|
||||
|
||||
int bar(int a) {
|
||||
a *= 2;
|
||||
a += 3;
|
||||
return a;
|
||||
}
|
||||
<File B: >
|
||||
int bar(int a) {
|
||||
a *= 2;
|
||||
a += 3;
|
||||
return a;
|
||||
}
|
||||
|
||||
int foo() {
|
||||
int n = 999;
|
||||
return n;
|
||||
}
|
||||
|
||||
int g = 1;
|
||||
<
|
||||
A normal diff will usually align the diff result as such: >
|
||||
|
||||
int foo() { |----------------
|
||||
int n = 1; |----------------
|
||||
return n; |----------------
|
||||
} |----------------
|
||||
|----------------
|
||||
int g = 1; |----------------
|
||||
|----------------
|
||||
int bar(int a) {|int bar(int a) {
|
||||
a *= 2; | a *= 2;
|
||||
a += 3; | a += 3;
|
||||
return a; | return a;
|
||||
} |}
|
||||
----------------|
|
||||
----------------|int foo() {
|
||||
----------------| int n = 999;
|
||||
----------------| return n;
|
||||
----------------|}
|
||||
----------------|
|
||||
----------------|int g = 1;
|
||||
<
|
||||
What we want is to instead ask the diff to align on `foo()`: >
|
||||
|
||||
----------------|int bar(int a) {
|
||||
----------------| a *= 2;
|
||||
----------------| a += 3;
|
||||
----------------| return a;
|
||||
----------------|}
|
||||
----------------|
|
||||
int foo() { |int foo() {
|
||||
int n = 1; | int n = 999;
|
||||
return n; | return n;
|
||||
} |}
|
||||
|
|
||||
int g = 1; |int g = 1;
|
||||
|----------------
|
||||
int bar(int a) {|----------------
|
||||
a *= 2; |----------------
|
||||
a += 3; |----------------
|
||||
return a; |----------------
|
||||
} |----------------
|
||||
<
|
||||
|
||||
Below are some ways of setting diff anchors to get the above result. In each
|
||||
example, 'diffopt' needs to have `anchor` set for this to take effect.
|
||||
|
||||
Marks: Set the |'a| mark on the `int foo()` lines in each file first before
|
||||
setting the anchors: >
|
||||
set diffanchors='a
|
||||
|
||||
Pattern: Specify the anchor using a |pattern| (see |:/|). Here, we make sure
|
||||
to always start search from line 1 for consistency: >
|
||||
set diffanchors=1/int\ foo(/
|
||||
<
|
||||
Selection: Use visual mode to select the entire `foo()` function body in each
|
||||
file. Here, we use two anchors. This does a better job of making sure only
|
||||
the function bodies are anchored against each other but not the lines after
|
||||
it. Note the `'>+1` below. The "+1" is necessary as we want the split to
|
||||
happen below the last line of the function, not above: >
|
||||
set diffanchors='<,'>+1
|
||||
<
|
||||
Manually set two anchors using line numbers via buffer-local options: >
|
||||
setlocal diffanchors=1,5
|
||||
wincmd w
|
||||
setlocal diffanchors=7,11
|
||||
<
|
||||
==============================================================================
|
||||
6. Diff options *diff-options*
|
||||
|
||||
Also see 'diffopt' and the "diff" item of 'fillchars'.
|
||||
|
||||
*diff-slow* *diff_translations*
|
||||
For very long lines, the diff syntax highlighting might be slow, especially
|
||||
|
@@ -1094,8 +1094,8 @@ the 1', 2' and 3' digraphs.
|
||||
⌕ TR 2315 8981 TELEPHONE RECORDER
|
||||
⌠ Iu 2320 8992 TOP HALF INTEGRAL
|
||||
⌡ Il 2321 8993 BOTTOM HALF INTEGRAL
|
||||
〈 </ 2329 9001 LEFT-POINTING ANGLE BRACKET
|
||||
〉 /> 232A 9002 RIGHT-POINTING ANGLE BRACKET
|
||||
⟨ <[ 27E8 10040 LEFT MATHEMATICAL ANGLE BRACKET
|
||||
⟩ ]> 27E9 10041 RIGHT MATHEMATICAL ANGLE BRACKET
|
||||
␣ Vs 2423 9251 OPEN BOX
|
||||
⑀ 1h 2440 9280 OCR HOOK
|
||||
⑁ 3h 2441 9281 OCR CHAIR
|
||||
|
@@ -630,7 +630,7 @@ list of the current window.
|
||||
buffer.
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
:[count]arge[dit][!] [++opt] [+cmd] {name} .. *:arge* *:argedit*
|
||||
:[count]arge[dit][!] [++opt] [+cmd] {name} ... *:arge* *:argedit*
|
||||
Add {name}s to the argument list and edit it.
|
||||
There is no check for duplicates, it is possible to
|
||||
add a file to the argument list twice |:argded|.
|
||||
@@ -645,7 +645,7 @@ list of the current window.
|
||||
edited. No check for duplicates is done.
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
:[count]arga[dd] {name} .. *:arga* *:argadd* *E479*
|
||||
:[count]arga[dd] {name} ... *:arga* *:argadd* *E479*
|
||||
:[count]arga[dd] *E1156*
|
||||
Add the {name}s to the argument list. When {name} is
|
||||
omitted add the current buffer name to the argument
|
||||
@@ -676,7 +676,7 @@ list of the current window.
|
||||
If your current file is a duplicate, your current file
|
||||
will change to the original file index.
|
||||
|
||||
:argd[elete] {pattern} .. *:argd* *:argdelete* *E480* *E610*
|
||||
:argd[elete] {pattern} ... *:argd* *:argdelete* *E480* *E610*
|
||||
Delete files from the argument list that match the
|
||||
{pattern}s. {pattern} is used like a file pattern,
|
||||
see |file-pattern|. "%" can be used to delete the
|
||||
@@ -714,11 +714,14 @@ list of the current window.
|
||||
omitted the current entry is used.
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
:[count]n[ext] [++opt] [+cmd] *:n* *:ne* *:next* *]a* *E165* *E163*
|
||||
:[count]n[ext] [++opt] [+cmd] *:n* *:ne* *:next* *E165* *E163*
|
||||
Edit [count] next file. This fails when changes have
|
||||
been made and Vim does not want to |abandon| the
|
||||
current buffer. Also see |++opt| and |+cmd|.
|
||||
|
||||
*]a*
|
||||
]a Mapped to |:next|. |default-mappings|
|
||||
|
||||
:[count]n[ext]! [++opt] [+cmd]
|
||||
Edit [count] next file, discard any changes to the
|
||||
buffer. Also see |++opt| and |+cmd|.
|
||||
@@ -740,16 +743,22 @@ list of the current window.
|
||||
any changes to the buffer. Also see |++opt| and
|
||||
|+cmd|.
|
||||
|
||||
:[count]prev[ious] [count] [++opt] [+cmd] *:prev* *:previous* *[a*
|
||||
:[count]prev[ious] [count] [++opt] [+cmd] *:prev* *:previous*
|
||||
Same as :Next. Also see |++opt| and |+cmd|.
|
||||
|
||||
*:rew* *:rewind* *[A*
|
||||
*[a*
|
||||
[a Mapped to |:previous|. |default-mappings|
|
||||
|
||||
*:rew* *:rewind*
|
||||
:rew[ind] [++opt] [+cmd]
|
||||
Start editing the first file in the argument list.
|
||||
This fails when changes have been made and Vim does
|
||||
not want to |abandon| the current buffer.
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
*[A*
|
||||
[A Mapped to |:rewind|. |default-mappings|
|
||||
|
||||
:rew[ind]! [++opt] [+cmd]
|
||||
Start editing the first file in the argument list.
|
||||
Discard any changes to the buffer. Also see |++opt|
|
||||
@@ -759,13 +768,16 @@ list of the current window.
|
||||
:fir[st][!] [++opt] [+cmd]
|
||||
Other name for ":rewind".
|
||||
|
||||
*:la* *:last* *]A*
|
||||
*:la* *:last*
|
||||
:la[st] [++opt] [+cmd]
|
||||
Start editing the last file in the argument list.
|
||||
This fails when changes have been made and Vim does
|
||||
not want to |abandon| the current buffer.
|
||||
Also see |++opt| and |+cmd|.
|
||||
|
||||
*]A*
|
||||
]A Mapped to |:last|. |default-mappings|
|
||||
|
||||
:la[st]! [++opt] [+cmd]
|
||||
Start editing the last file in the argument list.
|
||||
Discard any changes to the buffer. Also see |++opt|
|
||||
@@ -948,8 +960,9 @@ Note: When the 'write' option is off, you are not able to write any file.
|
||||
executed like with ":!{cmd}", any '!' is replaced with
|
||||
the previous command |:!|.
|
||||
|
||||
The default [range] for the ":w" command is the whole buffer (1,$). If you
|
||||
write the whole buffer, it is no longer considered changed. When you
|
||||
The default [range] for the ":w" command is the whole buffer (1,$). The |'[|
|
||||
and |']| marks will be set to the [range] being used for the write command.
|
||||
If you write the whole buffer, it is no longer considered changed. When you
|
||||
write it to a different file with ":w somefile" it depends on the "+" flag in
|
||||
'cpoptions'. When included, the write command will reset the 'modified' flag,
|
||||
even though the buffer itself may still be different from its file.
|
||||
@@ -1229,10 +1242,10 @@ MULTIPLE WINDOWS AND BUFFERS *window-exit*
|
||||
*:confirm* *:conf*
|
||||
:conf[irm] {command} Execute {command}, and use a dialog when an
|
||||
operation has to be confirmed. Can be used on the
|
||||
|:edit|, |:q|, |:qa| and |:w| commands (the latter to
|
||||
override a read-only setting), and any commands that
|
||||
can fail because of unsaved changes, such as |:only|,
|
||||
|:buffer|, |:bdelete|, etc.
|
||||
|:edit|, |:restart|, |:q|, |:qa| and |:w| commands
|
||||
(the latter to override a read-only setting), and any
|
||||
commands that can fail because of unsaved changes,
|
||||
such as |:only|, |:buffer|, |:bdelete|, etc.
|
||||
|
||||
Examples: >
|
||||
:confirm w foo
|
||||
@@ -1303,9 +1316,15 @@ b:browsefilter variable. You would most likely set b:browsefilter in a
|
||||
filetype plugin, so that the browse dialog would contain entries related to
|
||||
the type of file you are currently editing. Disadvantage: This makes it
|
||||
difficult to start editing a file of a different type. To overcome this, you
|
||||
may want to add "All Files (*.*)\t*\n" as the final filter on Windows or "All
|
||||
Files (*)\t*\n" on other platforms, so that the user can still access any
|
||||
desired file.
|
||||
can add the following as the final filter on Windows: >
|
||||
|
||||
All Files\t(*.*)\t*\n
|
||||
<
|
||||
Or the following on other platforms, so that the user can still access any
|
||||
desired file: >
|
||||
|
||||
All Files\t(*)\t*\n
|
||||
<
|
||||
|
||||
To avoid setting browsefilter when Vim does not actually support it, you can
|
||||
use has("browsefilter"): >
|
||||
@@ -1337,7 +1356,7 @@ exist, the next-higher scope in the hierarchy applies.
|
||||
|
||||
:cd[!] {path} Change the current directory to {path}.
|
||||
If {path} is relative, it is searched for in the
|
||||
directories listed in |'cdpath'|.
|
||||
directories listed in 'cdpath'.
|
||||
Clear any window-local directory.
|
||||
Does not change the meaning of an already opened file,
|
||||
because its full path name is remembered. Files from
|
||||
|
@@ -187,35 +187,28 @@ Run |:checkhealth| in Nvim for automatic diagnosis.
|
||||
|
||||
Other hints:
|
||||
|
||||
- The python `neovim` module was renamed to `pynvim` (long ago).
|
||||
- If you're using pyenv or virtualenv for the `pynvim` module
|
||||
https://pypi.org/project/pynvim/, you must set `g:python3_host_prog` to
|
||||
the virtualenv's interpreter path.
|
||||
- Read |provider-python|.
|
||||
- Read |provider-python| to learn how to install `pynvim`.
|
||||
- Be sure you have the latest version of the `pynvim` Python module: >bash
|
||||
|
||||
python -m pip install setuptools
|
||||
python -m pip install --upgrade pynvim
|
||||
python3 -m pip install --upgrade pynvim
|
||||
uv tool install --upgrade pynvim
|
||||
<
|
||||
See |provider-python| for other installation options.
|
||||
- If you're manually creating a Python virtual environment for the `pynvim` module
|
||||
https://pypi.org/project/pynvim/, you must set `g:python3_host_prog` to
|
||||
the virtualenv's interpreter path.
|
||||
- Try with `nvim -u NORC` to make sure your config (|init.vim|) isn't causing a
|
||||
problem. If you get `E117: Unknown function`, that means there's a runtime
|
||||
issue: |faq-runtime|.
|
||||
- The python `neovim` module was renamed to `pynvim` (long ago).
|
||||
|
||||
|
||||
:CHECKHEALTH REPORTS E5009: INVALID $VIMRUNTIME ~
|
||||
|
||||
This means `health#check()` couldn't load, which suggests that |$VIMRUNTIME|
|
||||
or 'runtimepath' is broken.
|
||||
This means |$VIMRUNTIME| or 'runtimepath' is broken.
|
||||
|
||||
- |$VIMRUNTIME| must point to Nvim's runtime files, not Vim's.
|
||||
- The |$VIMRUNTIME| directory contents should be readable by the current user.
|
||||
- Verify that `:echo &runtimepath` contains the $VIMRUNTIME path.
|
||||
- Check the output of: >vim
|
||||
|
||||
:call health#check()
|
||||
:verbose func health#check
|
||||
<
|
||||
|
||||
NEOVIM CAN'T FIND ITS RUNTIME ~
|
||||
|
||||
@@ -456,10 +449,7 @@ grow and enhance it. Changing the rules of Lua gains nothing in this context.
|
||||
|
||||
WILL NEOVIM TRANSLATE VIMSCRIPT TO LUA, INSTEAD OF EXECUTING VIMSCRIPT DIRECTLY? ~
|
||||
|
||||
- We are experimenting with vim9jit https://github.com/tjdevries/vim9jit to
|
||||
transpile Vim9script (Vim9's Vimscript variant) to Lua and have used this to
|
||||
port Vim9 plugins https://github.com/neovim/neovim/pull/21662 to Nvim Lua.
|
||||
- We have no plans for transpiling legacy Vimscript.
|
||||
We have no plans for transpiling Vimscript. It was explored in https://github.com/tjdevries/vim9jit
|
||||
|
||||
|
||||
ARE PLUGIN AUTHORS ENCOURAGED TO PORT THEIR PLUGINS FROM VIMSCRIPT TO LUA? DO YOU PLAN ON SUPPORTING VIMSCRIPT INDEFINITELY? (#1152) ~
|
||||
@@ -474,4 +464,8 @@ emphatically a fork of Vim in order to leverage the work already spent on
|
||||
thousands of Vim plugins, while enabling new types of plugins and
|
||||
integrations.
|
||||
|
||||
That being said, reimplementing legacy plugins in Lua in order to make use of
|
||||
Nvim API and to integrate with Nvim-specific features such as treesitter can
|
||||
be worthwhile.
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -156,6 +156,8 @@ variables can be used to overrule the filetype used for certain extensions:
|
||||
`*.inc` g:filetype_inc
|
||||
`*.lsl` g:filetype_lsl
|
||||
`*.m` g:filetype_m |ft-mathematica-syntax|
|
||||
`*[mM]makefile,*.mk,*.mak,[mM]akefile*`
|
||||
g:make_flavor |ft-make-syntax|
|
||||
`*.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md`
|
||||
g:filetype_md |ft-pandoc-syntax|
|
||||
`*.mod` g:filetype_mod
|
||||
@@ -262,7 +264,7 @@ D. If your filetype can only be detected by inspecting the contents of the
|
||||
item of the 'runtimepath' option. Example for Unix: >
|
||||
:!mkdir -p ~/.config/nvim
|
||||
<
|
||||
2. Create a vim script file for doing this. Example: >
|
||||
2. Create a Vim script file for doing this. Example: >
|
||||
if did_filetype() " filetype already set..
|
||||
finish " ..don't do these checks
|
||||
endif
|
||||
@@ -623,6 +625,16 @@ possibilities: >
|
||||
The `:Cycle` command is also mapped to the CTRL-A and CTRL-X keys.
|
||||
For details, see `git-rebase --help`.
|
||||
|
||||
GLEAM *ft-gleam-plugin*
|
||||
|
||||
By default the following options are set for the recommended gleam style: >
|
||||
|
||||
setlocal expandtab shiftwidth=2 softtabstop=2
|
||||
|
||||
To disable this behavior, set the following variable in your vimrc: >
|
||||
|
||||
let g:gleam_recommended_style = 0
|
||||
|
||||
GO *ft-go-plugin*
|
||||
|
||||
By default the following options are set, based on Golang official docs: >
|
||||
@@ -649,6 +661,32 @@ HARE *ft-hare*
|
||||
Since the text for this plugin is rather long it has been put in a separate
|
||||
file: |ft_hare.txt|.
|
||||
|
||||
HTML *ft-html-plugin*
|
||||
|
||||
Tag folding poses a few difficulties. Many elements, e.g. `blockquote`, are
|
||||
always delimited by start and end tags; end tags for some elements, e.g. `p`,
|
||||
can be omitted in certain contexts; void elements, e.g. `hr`, have no end tag.
|
||||
Although the rules for supporting omissible end tags are ad-hoc and involved
|
||||
[0], they apply to elements in scope. Assuming syntactical wellformedness, an
|
||||
end tag can be associated with its nearest matching start tag discoverable in
|
||||
scope [1] and towards the beginning of a file, whereas all unbalanced tags and
|
||||
inlined tags can be disregarded. Having syntax highlighting in effect, tag
|
||||
folding using the |fold-expr| method can be enabled with: >
|
||||
let g:html_expr_folding = 1
|
||||
<
|
||||
By default, tag folding will be redone from scratch after each occurrence of
|
||||
a |TextChanged| or an |InsertLeave| event. Such frequency may not be desired,
|
||||
especially for large files, and this recomputation can be disabled with: >
|
||||
let g:html_expr_folding_without_recomputation = 1
|
||||
doautocmd FileType
|
||||
<
|
||||
To force another recomputation, do: >
|
||||
unlet! b:foldsmap
|
||||
normal zx
|
||||
<
|
||||
[0] https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
||||
[1] https://en.wikipedia.org/wiki/Dangling_else
|
||||
|
||||
IDRIS2 *ft-idris2-plugin*
|
||||
|
||||
By default the following options are set: >
|
||||
@@ -785,8 +823,8 @@ Variables:
|
||||
For example in C one usually wants section 3 or 2: >
|
||||
:let b:man_default_sections = '3,2'
|
||||
*g:man_hardwrap* Hard-wrap to $MANWIDTH or window width if $MANWIDTH is
|
||||
empty. Enabled by default. Set |FALSE| to enable soft
|
||||
wrapping.
|
||||
empty or larger than the window width. Enabled by
|
||||
default. Set |FALSE| to enable soft wrapping.
|
||||
|
||||
To use Nvim as a manpager: >bash
|
||||
export MANPAGER='nvim +Man!'
|
||||
@@ -1117,6 +1155,13 @@ functions with [[ and ]]. Move around comments with ]" and [".
|
||||
The mappings can be disabled with: >
|
||||
let g:no_vim_maps = 1
|
||||
|
||||
YAML *ft-yaml-plugin*
|
||||
By default, the YAML filetype plugin enables the following options: >
|
||||
setlocal shiftwidth=2 softtabstop=2
|
||||
|
||||
To disable this, set the following variable: >
|
||||
let g:yaml_recommended_style = 0
|
||||
|
||||
|
||||
ZIG *ft-zig-plugin*
|
||||
|
||||
|
@@ -632,14 +632,17 @@ what you type!
|
||||
When using an operator, a closed fold is included as a whole. Thus "dl"
|
||||
deletes the whole closed fold under the cursor.
|
||||
|
||||
For Ex commands that work on buffer lines the range is adjusted to always
|
||||
For Ex commands that operate on buffer lines, the range is adjusted to always
|
||||
start at the first line of a closed fold and end at the last line of a closed
|
||||
fold. Thus this command: >
|
||||
fold. Thus, this command: >
|
||||
:s/foo/bar/g
|
||||
when used with the cursor on a closed fold, will replace "foo" with "bar" in
|
||||
all lines of the fold.
|
||||
This does not happen for |:folddoopen| and |:folddoclosed|.
|
||||
|
||||
Note that for some Ex commands like |:source| the range is only adjusted when
|
||||
using a two line specifiers [range].
|
||||
|
||||
When editing a buffer that has been edited before, the last used folding
|
||||
settings are used again. For manual folding the defined folds are restored.
|
||||
For all folding methods the manually opened and closed folds are restored.
|
||||
@@ -647,5 +650,4 @@ If this buffer has been edited in this window, the values from back then are
|
||||
used. Otherwise the values from the window where the buffer was edited last
|
||||
are used.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -76,8 +76,8 @@ The Ada plug-in provides support for:
|
||||
- user completion (|i_CTRL-X_CTRL-U|)
|
||||
- tag searches (|tagsrch.txt|)
|
||||
- Quick Fix (|quickfix.txt|)
|
||||
- backspace handling (|'backspace'|)
|
||||
- comment handling (|'comments'|, |'commentstring'|)
|
||||
- backspace handling ('backspace')
|
||||
- comment handling ('comments', 'commentstring')
|
||||
|
||||
The plug-in only activates the features of the Ada mode whenever an Ada
|
||||
file is opened and adds Ada related entries to the main and pop-up menu.
|
||||
@@ -197,7 +197,7 @@ g:gnat.Project_File string
|
||||
|
||||
*g:gnat.Make_Command*
|
||||
g:gnat.Make_Command string
|
||||
External command used for |g:gnat.Make()| (|'makeprg'|).
|
||||
External command used for |g:gnat.Make()| ('makeprg').
|
||||
|
||||
*g:gnat.Pretty_Program*
|
||||
g:gnat.Pretty_Program string
|
||||
@@ -213,7 +213,7 @@ g:gnat.Tags_Command string
|
||||
|
||||
*g:gnat.Error_Format*
|
||||
g:gnat.Error_Format string
|
||||
Error format (|'errorformat'|)
|
||||
Error format ('errorformat')
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
4.2 Dec Ada ~
|
||||
@@ -243,11 +243,11 @@ g:decada.Unit_Name() function
|
||||
|
||||
*g:decada.Make_Command*
|
||||
g:decada.Make_Command string
|
||||
External command used for |g:decada.Make()| (|'makeprg'|).
|
||||
External command used for |g:decada.Make()| ('makeprg').
|
||||
|
||||
*g:decada.Error_Format*
|
||||
g:decada.Error_Format string
|
||||
Error format (|'errorformat'|).
|
||||
Error format ('errorformat').
|
||||
|
||||
==============================================================================
|
||||
5. References ~
|
||||
@@ -507,6 +507,4 @@ taglist.vim
|
||||
The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim
|
||||
contains all of the above.
|
||||
|
||||
==============================================================================
|
||||
vim: textwidth=78 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab
|
||||
vim: filetype=help
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -73,5 +73,4 @@ The maximum search depth can be set to any integer, but using values higher
|
||||
than 2 is not recommended, and will likely provide no tangible benefit in most
|
||||
situations.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -60,5 +60,4 @@ Many other distributions are available for Windows like
|
||||
https://chocolatey.org/packages/less/. Make sure `less` is in a directory
|
||||
listed in the `PATH` environment variable, which chocolatey above does.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
vim:ft=help:
|
||||
|
@@ -160,7 +160,18 @@ g:rustfmt_emit_files ~
|
||||
provided) instead of '--write-mode=overwrite'. >vim
|
||||
let g:rustfmt_emit_files = 0
|
||||
<
|
||||
|
||||
*g:rustfmt_detect_version*
|
||||
g:rustfmt_detect_version ~
|
||||
When set to 1, will try to parse the version output from "rustfmt".
|
||||
Disabled by default for performance reasons >vim
|
||||
let g:rustfmt_detect_version = 1
|
||||
<
|
||||
*g:rustfmt_find_toml*
|
||||
g:rustfmt_emit_files ~
|
||||
When set to 1, will try to find "rustfmt.toml" file by searching from
|
||||
current path upwards. Disabled by default for performance reasons >vim
|
||||
let g:rustfmt_find_toml = 1
|
||||
<
|
||||
*g:rust_playpen_url*
|
||||
g:rust_playpen_url ~
|
||||
Set this option to override the url for the playpen to use: >vim
|
||||
@@ -475,4 +486,4 @@ MAPPINGS *rust-mappings*
|
||||
This plugin defines mappings for |[[| and |]]| to support hanging indents.
|
||||
|
||||
|
||||
vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
|
||||
vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
|
||||
|
@@ -172,7 +172,7 @@ with comments: >
|
||||
------------------------------------------------------------------------------
|
||||
1.4 Macros *sql-macros*
|
||||
|
||||
Vim's feature to find macro definitions, |'define'|, is supported using this
|
||||
Vim's feature to find macro definitions, 'define', is supported using this
|
||||
regular expression: >
|
||||
\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>
|
||||
|
||||
@@ -249,7 +249,7 @@ key to complete the optional parameter.
|
||||
After typing the function name and a space, you can use the completion to
|
||||
supply a parameter. The function takes the name of the Vim script you want to
|
||||
source. Using the |cmdline-completion| feature, the SQLSetType function will
|
||||
search the |'runtimepath'| for all Vim scripts with a name containing "sql".
|
||||
search the 'runtimepath' for all Vim scripts with a name containing "sql".
|
||||
This takes the guess work out of the spelling of the names. The following are
|
||||
examples: >
|
||||
:SQLSetType
|
||||
@@ -412,7 +412,7 @@ Here are some examples of the entries which are pulled from the syntax files: >
|
||||
|
||||
Dynamic mode populates the popups with data directly from a database. In
|
||||
order for the dynamic feature to be enabled you must have the dbext.vim
|
||||
plugin installed, (https://vim.sourceforge.net/script.php?script_id=356).
|
||||
plugin installed, (https://www.vim.org/scripts/script.php?script_id=356).
|
||||
|
||||
Dynamic mode is used by several features of the SQL completion plugin.
|
||||
After installing the dbext plugin see the dbext-tutorial for additional
|
||||
@@ -496,7 +496,7 @@ depending on the syntax file you are using. The SQL Anywhere syntax file
|
||||
Dynamic features ~
|
||||
|
||||
To take advantage of the dynamic features you must first install the
|
||||
dbext.vim plugin (https://vim.sourceforge.net/script.php?script_id=356). It
|
||||
dbext.vim plugin (https://www.vim.org/scripts/script.php?script_id=356). It
|
||||
also comes with a tutorial. From the SQL completion plugin's perspective,
|
||||
the main feature dbext provides is a connection to a database. dbext
|
||||
connection profiles are the most efficient mechanism to define connection
|
||||
@@ -760,7 +760,7 @@ Step 1 ~
|
||||
Begins by editing a Perl file. Vim automatically sets the filetype to
|
||||
"perl". By default, Vim runs the appropriate filetype file
|
||||
ftplugin/perl.vim. If you are using the syntax completion plugin by following
|
||||
the directions at |ft-syntax-omni| then the |'omnifunc'| option has been set to
|
||||
the directions at |ft-syntax-omni| then the 'omnifunc' option has been set to
|
||||
"syntax#Complete". Pressing <C-X><C-O> will display the omni popup containing
|
||||
the syntax items for Perl.
|
||||
|
||||
@@ -772,7 +772,7 @@ maps for SQL completion, see |sql-completion-maps|. Now these maps have
|
||||
been created and the SQL completion plugin has been initialized. All SQL
|
||||
syntax items have been cached in preparation. The SQL filetype script detects
|
||||
we are attempting to use two different completion plugins. Since the SQL maps
|
||||
begin with <C-C>, the maps will toggle the |'omnifunc'| when in use. So you
|
||||
begin with <C-C>, the maps will toggle the 'omnifunc' when in use. So you
|
||||
can use <C-X><C-O> to continue using the completion for Perl (using the syntax
|
||||
completion plugin) and <C-C> to use the SQL completion features.
|
||||
|
||||
|
@@ -17,6 +17,8 @@ TUI and GUI (assuming the UI supports the given feature). See |TUI| for notes
|
||||
specific to the terminal UI. Help tags with the "gui-" prefix refer to UI
|
||||
features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
Third-party GUIs *third-party-guis* *vscode*
|
||||
|
||||
@@ -34,8 +36,6 @@ a Nvim GUI.
|
||||
- VimR (macOS) https://github.com/qvacua/vimr
|
||||
- Others https://github.com/neovim/neovim/wiki/Related-projects#gui
|
||||
|
||||
Type |gO| to see the table of contents.
|
||||
|
||||
==============================================================================
|
||||
Starting the GUI *gui-config* *gui-start*
|
||||
|
||||
@@ -64,7 +64,50 @@ Stop or detach the current UI
|
||||
the channel to be closed, it may be (incorrectly) reported as
|
||||
an error.
|
||||
|
||||
Note: Not supported on Windows, currently.
|
||||
Note: Not supported on Windows yet.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Restart Nvim
|
||||
|
||||
*:restart*
|
||||
:restart [+cmd] [command]
|
||||
Restarts Nvim.
|
||||
|
||||
1. Stops Nvim using `:qall!` (or |+cmd|, if given).
|
||||
2. Starts a new Nvim server using the same |v:argv|,
|
||||
optionally running [command] at startup. |-c|
|
||||
3. Attaches the current UI to the new Nvim server. Other UIs
|
||||
(if any) will not reattach on restart (this may change in
|
||||
the future).
|
||||
|
||||
Use with `:confirm` to prompt if changes have been made.
|
||||
|
||||
Example: stop with `:qall!`, then restart: >
|
||||
:restart +qall!
|
||||
< Example: restart and restore the current session: >
|
||||
:mksession! Session.vim | restart source Session.vim
|
||||
< Example: restart and update plugins: >
|
||||
:restart +qall! lua vim.pack.update()
|
||||
<
|
||||
Note: Only works if the UI and server are on the same system.
|
||||
Note: If the UI hasn't implemented the "restart" UI event,
|
||||
this command is equivalent to `:qall!`.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Connect UI to a different server
|
||||
|
||||
*:connect*
|
||||
|
||||
:connect {address}
|
||||
Detaches the UI from the server it is currently attached to
|
||||
and attaches it to the server at {address} instead.
|
||||
|
||||
Note: If the current UI hasn't implemented the "connect" UI
|
||||
event, this command is equivalent to |:detach|.
|
||||
|
||||
:connect! {address}
|
||||
Same as |:connect| but it also stops the detached server if
|
||||
no other UI is currently attached to it.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
GUI commands
|
||||
|
@@ -9,18 +9,18 @@
|
||||
==============================================================================
|
||||
Checkhealth *vim.health* *health*
|
||||
|
||||
|
||||
vim.health is a minimal framework to help users troubleshoot configuration and
|
||||
any other environment conditions that a plugin might care about. Nvim ships
|
||||
with healthchecks for configuration, performance, python support, ruby
|
||||
support, clipboard support, and more.
|
||||
|
||||
To run all healthchecks, use: >vim
|
||||
|
||||
:checkhealth
|
||||
:checkhealth
|
||||
<
|
||||
|
||||
Plugin authors are encouraged to write new healthchecks. |health-dev|
|
||||
|
||||
|
||||
COMMANDS *health-commands*
|
||||
|
||||
*:che* *:checkhealth*
|
||||
@@ -56,7 +56,6 @@ Local mappings in the healthcheck buffer:
|
||||
q Closes the window.
|
||||
|
||||
Global configuration:
|
||||
|
||||
*g:health*
|
||||
g:health Dictionary with the following optional keys:
|
||||
- `style` (`'float'|nil`) Set to "float" to display :checkhealth in
|
||||
@@ -65,16 +64,26 @@ g:health Dictionary with the following optional keys:
|
||||
Example: >lua
|
||||
vim.g.health = { style = 'float' }
|
||||
|
||||
|
||||
Local configuration:
|
||||
|
||||
Checkhealth sets its buffer filetype to "checkhealth". You can customize the
|
||||
buffer by handling the |FileType| event. For example if you don't want emojis
|
||||
in the health report: >vim
|
||||
autocmd FileType checkhealth :set modifiable | silent! %s/\v( ?[^\x00-\x7F])//g
|
||||
<
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Create a healthcheck *health-dev*
|
||||
|
||||
Healthchecks are functions that check the user environment, configuration, or
|
||||
any other prerequisites that a plugin cares about. Nvim ships with
|
||||
healthchecks in:
|
||||
- $VIMRUNTIME/autoload/health/
|
||||
- $VIMRUNTIME/lua/vim/lsp/health.lua
|
||||
- $VIMRUNTIME/lua/vim/treesitter/health.lua
|
||||
- and more...
|
||||
• $VIMRUNTIME/autoload/health/
|
||||
• $VIMRUNTIME/lua/vim/lsp/health.lua
|
||||
• $VIMRUNTIME/lua/vim/treesitter/health.lua
|
||||
• and more...
|
||||
|
||||
To add a new healthcheck for your own plugin, simply create a "health.lua"
|
||||
module on 'runtimepath' that returns a table with a "check()" function. Then
|
||||
@@ -82,35 +91,35 @@ module on 'runtimepath' that returns a table with a "check()" function. Then
|
||||
|
||||
For example if your plugin is named "foo", define your healthcheck module at
|
||||
one of these locations (on 'runtimepath'):
|
||||
- lua/foo/health/init.lua
|
||||
- lua/foo/health.lua
|
||||
• lua/foo/health/init.lua
|
||||
• lua/foo/health.lua
|
||||
|
||||
If your plugin also provides a submodule named "bar" for which you want
|
||||
a separate healthcheck, define the healthcheck at one of these locations:
|
||||
- lua/foo/bar/health/init.lua
|
||||
- lua/foo/bar/health.lua
|
||||
If your plugin also provides a submodule named "bar" for which you want a
|
||||
separate healthcheck, define the healthcheck at one of these locations:
|
||||
• lua/foo/bar/health/init.lua
|
||||
• lua/foo/bar/health.lua
|
||||
|
||||
All such health modules must return a Lua table containing a `check()`
|
||||
function.
|
||||
|
||||
Copy this sample code into `lua/foo/health.lua`, replacing "foo" in the path
|
||||
with your plugin name: >lua
|
||||
local M = {}
|
||||
|
||||
local M = {}
|
||||
M.check = function()
|
||||
vim.health.start("foo report")
|
||||
-- make sure setup function parameters are ok
|
||||
if check_setup() then
|
||||
vim.health.ok("Setup is correct")
|
||||
else
|
||||
vim.health.error("Setup is incorrect")
|
||||
end
|
||||
-- do some more checking
|
||||
-- ...
|
||||
end
|
||||
|
||||
M.check = function()
|
||||
vim.health.start("foo report")
|
||||
-- make sure setup function parameters are ok
|
||||
if check_setup() then
|
||||
vim.health.ok("Setup is correct")
|
||||
else
|
||||
vim.health.error("Setup is incorrect")
|
||||
end
|
||||
-- do some more checking
|
||||
-- ...
|
||||
end
|
||||
|
||||
return M
|
||||
return M
|
||||
<
|
||||
|
||||
|
||||
error({msg}, {...}) *vim.health.error()*
|
||||
|
@@ -112,7 +112,6 @@ API (EXTENSIBILITY/SCRIPTING/PLUGINS)
|
||||
|channel| Nvim asynchronous IO
|
||||
|vimscript| Vimscript reference
|
||||
|vimscript-functions| Vimscript functions
|
||||
|testing.txt| Vimscript testing functions
|
||||
|remote-plugin| Nvim remote plugins
|
||||
|health| Health checking
|
||||
|
||||
|
@@ -337,7 +337,7 @@ in such a modeline, that can have undesired consequences.
|
||||
|
||||
TAGS
|
||||
|
||||
To define a help tag, place the name between asterisks (*tag-name*). The
|
||||
To define a help tag, place the name between asterisks ("*tag-name*"). The
|
||||
tag-name should be different from all the Vim help tag names and ideally
|
||||
should begin with the name of the Vim plugin. The tag name is usually right
|
||||
aligned on a line.
|
||||
@@ -373,11 +373,17 @@ To quote a block of ex-commands verbatim, place a greater than (>) character
|
||||
at the end of the line before the block and a less than (<) character as the
|
||||
first non-blank on a line following the block. Any line starting in column 1
|
||||
also implicitly stops the block of ex-commands before it. E.g. >
|
||||
function Example_Func()
|
||||
echo "Example"
|
||||
endfunction
|
||||
function Example_Func()
|
||||
echo "Example"
|
||||
endfunction
|
||||
<
|
||||
|
||||
To enable syntax highlighting for a block of code, place a language name
|
||||
annotation (e.g. "vim") after a greater than (>) character. E.g. >vim
|
||||
function Example_Func()
|
||||
echo "Example"
|
||||
endfunction
|
||||
<
|
||||
*help-notation*
|
||||
The following are highlighted differently in a Vim help file:
|
||||
- a special key name expressed either in <> notation as in <PageDown>, or
|
||||
as a Ctrl character as in CTRL-X
|
||||
@@ -391,4 +397,10 @@ highlighting. So do these:
|
||||
You can find the details in $VIMRUNTIME/syntax/help.vim
|
||||
|
||||
|
||||
FILETYPE COMPLETION *ft-help-omni*
|
||||
|
||||
To get completion for help tags when writing a tag reference, you can use the
|
||||
|i_CTRL-X_CTRL-O| command.
|
||||
|
||||
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -268,5 +268,4 @@ These are also available via the "main" package:
|
||||
$main::curwin The current Window object.
|
||||
$main::curbuf The current Buffer object.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -645,6 +645,6 @@ To check if `pyx*` functions and commands are available: >vim
|
||||
if has('pythonx')
|
||||
echo 'pyx* commands are available. (Python ' .. &pyx .. ')'
|
||||
endif
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -189,5 +189,4 @@ evaluate Ruby expressions and pass their values to Vim script.
|
||||
The Ruby value "true", "false" and "nil" are converted to v:true, v:false and
|
||||
v:null, respectively.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@@ -146,6 +146,7 @@ commands in CTRL-X submode *i_CTRL-X_index*
|
||||
|i_CTRL-X_CTRL-N| CTRL-X CTRL-N next completion
|
||||
|i_CTRL-X_CTRL-O| CTRL-X CTRL-O omni completion
|
||||
|i_CTRL-X_CTRL-P| CTRL-X CTRL-P previous completion
|
||||
|i_CTRL-X_CTRL-R| CTRL-X CTRL-R complete contents from registers
|
||||
|i_CTRL-X_CTRL-S| CTRL-X CTRL-S spelling suggestions
|
||||
|i_CTRL-X_CTRL-T| CTRL-X CTRL-T complete identifiers from thesaurus
|
||||
|i_CTRL-X_CTRL-Y| CTRL-X CTRL-Y scroll down
|
||||
@@ -515,7 +516,7 @@ tag command action in op-pending and Visual mode ~
|
||||
tag command action in Normal mode ~
|
||||
------------------------------------------------------------------------------ ~
|
||||
|CTRL-W_CTRL-B| CTRL-W CTRL-B same as "CTRL-W b"
|
||||
|CTRL-W_CTRL-C| CTRL-W CTRL-C same as "CTRL-W c"
|
||||
|CTRL-W_CTRL-C| CTRL-W CTRL-C no-op
|
||||
|CTRL-W_CTRL-D| CTRL-W CTRL-D same as "CTRL-W d"
|
||||
|CTRL-W_CTRL-F| CTRL-W CTRL-F same as "CTRL-W f"
|
||||
CTRL-W CTRL-G same as "CTRL-W g .."
|
||||
@@ -1016,7 +1017,7 @@ tag command action in Command-line editing mode ~
|
||||
|c_CTRL-D| CTRL-D list completions that match the pattern in
|
||||
front of the cursor
|
||||
|c_CTRL-E| CTRL-E cursor to end of command-line
|
||||
|'cedit'| CTRL-F default value for 'cedit': opens the
|
||||
'cedit' CTRL-F default value for 'cedit': opens the
|
||||
command-line window; otherwise not used
|
||||
|c_CTRL-G| CTRL-G next match when 'incsearch' is active
|
||||
|c_<BS>| <BS> delete the character in front of the cursor
|
||||
@@ -1265,6 +1266,7 @@ tag command action ~
|
||||
|:delcommand| :delc[ommand] delete user-defined command
|
||||
|:delfunction| :delf[unction] delete a user function
|
||||
|:delmarks| :delm[arks] delete marks
|
||||
|:detach| :detach detach the current UI
|
||||
|:diffupdate| :dif[fupdate] update 'diff' buffers
|
||||
|:diffget| :diffg[et] remove differences in current buffer
|
||||
|:diffoff| :diffo[ff] switch off diff mode
|
||||
@@ -1348,6 +1350,8 @@ tag command action ~
|
||||
|:inoreabbrev| :inorea[bbrev] like ":noreabbrev" but for Insert mode
|
||||
|:inoremenu| :inoreme[nu] like ":noremenu" but for Insert mode
|
||||
|:intro| :int[ro] print the introductory message
|
||||
|:iput| :ip[ut] like |:put|, but adjust the indent to the
|
||||
current line
|
||||
|:isearch| :is[earch] list one line where identifier matches
|
||||
|:isplit| :isp[lit] split window and jump to definition of
|
||||
identifier
|
||||
@@ -1469,7 +1473,6 @@ tag command action ~
|
||||
|:options| :opt[ions] open the options-window
|
||||
|:ounmap| :ou[nmap] like ":unmap" but for Operator-pending mode
|
||||
|:ounmenu| :ounme[nu] remove menu for Operator-pending mode
|
||||
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|
||||
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|
||||
|:packloadall| :packl[oadall] load all packages under 'packpath'
|
||||
|:pbuffer| :pb[uffer] edit buffer in the preview window
|
||||
@@ -1522,6 +1525,7 @@ tag command action ~
|
||||
|:redrawtabline| :redrawt[abline] force a redraw of the tabline
|
||||
|:registers| :reg[isters] display the contents of registers
|
||||
|:resize| :res[ize] change current window height
|
||||
|:restart| :restart restart the Nvim server
|
||||
|:retab| :ret[ab] change tab size
|
||||
|:return| :retu[rn] return from a user function
|
||||
|:rewind| :rew[ind] go to the first file in the argument list
|
||||
@@ -1663,6 +1667,7 @@ tag command action ~
|
||||
|:unabbreviate| :una[bbreviate] remove abbreviation
|
||||
|:unhide| :unh[ide] open a window for each loaded file in the
|
||||
buffer list
|
||||
|:uniq| :uni[q] uniq lines
|
||||
|:unlet| :unl[et] delete variable
|
||||
|:unlockvar| :unlo[ckvar] unlock variables
|
||||
|:unmap| :unm[ap] remove mapping
|
||||
|
@@ -29,7 +29,7 @@ use "CTRL-V 003" to insert a CTRL-C. Note: When CTRL-V is mapped you can
|
||||
often use CTRL-Q instead |i_CTRL-Q|.
|
||||
|
||||
If you are working in a special language mode when inserting text, see the
|
||||
'langmap' option, |'langmap'|, on how to avoid switching this mode on and off
|
||||
'langmap' option, 'langmap', on how to avoid switching this mode on and off
|
||||
all the time.
|
||||
|
||||
char action ~
|
||||
@@ -269,15 +269,17 @@ The effect of the <BS>, CTRL-W, and CTRL-U depend on the 'backspace' option
|
||||
|
||||
item action ~
|
||||
indent allow backspacing over autoindent
|
||||
eol allow backspacing over end-of-line (join lines)
|
||||
start allow backspacing over the start position of insert; CTRL-W and
|
||||
CTRL-U stop once at the start position
|
||||
eol allow backspacing over line breaks (join lines)
|
||||
start allow backspacing over the start of insert; CTRL-W and CTRL-U stop
|
||||
once at the start of insert.
|
||||
nostop like start, except CTRL-W and CTRL-U do not stop at the start of
|
||||
insert.
|
||||
|
||||
When 'backspace' is empty, Vi compatible backspacing is used. You cannot
|
||||
backspace over autoindent, before column 1 or before where insert started.
|
||||
|
||||
For backwards compatibility the values "0", "1", "2" and "3" are also allowed,
|
||||
see |'backspace'|.
|
||||
see 'backspace'.
|
||||
|
||||
If the 'backspace' option does contain "eol" and the cursor is in column 1
|
||||
when one of the three keys is used, the current line is joined with the
|
||||
@@ -510,7 +512,7 @@ paragraph, no matter where the cursor currently is. Or you can use Visual
|
||||
mode: hit "v", move to the end of the block, and type "gq". See also |gq|.
|
||||
|
||||
==============================================================================
|
||||
4. 'expandtab', 'smarttab' and 'softtabstop' options *ins-expandtab*
|
||||
4. 'expandtab', 'softtabstop' and 'smarttab' options *ins-expandtab*
|
||||
|
||||
If the 'expandtab' option is on, spaces will be used to fill the amount of
|
||||
whitespace of the tab. If you want to enter a real <Tab>, type CTRL-V first
|
||||
@@ -521,13 +523,6 @@ number of characters in the line increases. Backspacing will delete one
|
||||
space at a time. The original character will be put back for only one space
|
||||
that you backspace over (the last one).
|
||||
|
||||
*ins-smarttab*
|
||||
When the 'smarttab' option is on, a <Tab> inserts 'shiftwidth' positions at
|
||||
the beginning of a line and 'tabstop' positions in other places. This means
|
||||
that often spaces instead of a <Tab> character are inserted. When 'smarttab'
|
||||
is off, a <Tab> always inserts 'tabstop' positions, and 'shiftwidth' is only
|
||||
used for ">>" and the like.
|
||||
|
||||
*ins-softtabstop*
|
||||
When the 'softtabstop' option is non-zero, a <Tab> inserts 'softtabstop'
|
||||
positions, and a <BS> used to delete white space, will delete 'softtabstop'
|
||||
@@ -542,6 +537,13 @@ the cursor. Otherwise you cannot always delete a single character before the
|
||||
cursor. You will have to delete 'softtabstop' characters first, and then type
|
||||
extra spaces to get where you want to be.
|
||||
|
||||
*ins-smarttab*
|
||||
When the 'smarttab' option is on, the <Tab> key indents by 'shiftwidth' if the
|
||||
cursor is in leading whitespace. The <BS> key has the opposite effect. This
|
||||
behaves as if 'softtabstop' were set to the value of 'shiftwidth'. This option
|
||||
allows the user to set 'softtabstop' to a value other than 'shiftwidth' and
|
||||
still use the <Tab> key for indentation.
|
||||
|
||||
==============================================================================
|
||||
5. Replace mode *Replace* *Replace-mode* *mode-replace*
|
||||
|
||||
@@ -599,7 +601,7 @@ In 'list' mode, Virtual Replace mode acts as if it was not in 'list' mode,
|
||||
unless "L" is in 'cpoptions'.
|
||||
|
||||
Note that the only situations for which characters beyond the cursor should
|
||||
appear to move are in List mode |'list'|, and occasionally when 'wrap' is set
|
||||
appear to move are in List mode 'list', and occasionally when 'wrap' is set
|
||||
(and the line changes length to become shorter or wider than the width of the
|
||||
screen). In other cases spaces may be inserted to avoid following characters
|
||||
to move.
|
||||
@@ -628,7 +630,8 @@ Completion can be done for:
|
||||
10. User defined completion |i_CTRL-X_CTRL-U|
|
||||
11. omni completion |i_CTRL-X_CTRL-O|
|
||||
12. Spelling suggestions |i_CTRL-X_s|
|
||||
13. keywords in 'complete' |i_CTRL-N| |i_CTRL-P|
|
||||
13. completions from 'complete' |i_CTRL-N| |i_CTRL-P|
|
||||
14. contents from registers |i_CTRL-X_CTRL-R|
|
||||
|
||||
Additionally, |i_CTRL-X_CTRL-Z| stops completion without changing the text.
|
||||
|
||||
@@ -638,6 +641,9 @@ and one of the CTRL-X commands. You exit CTRL-X mode by typing a key that is
|
||||
not a valid CTRL-X mode command. Valid keys are the CTRL-X command itself,
|
||||
CTRL-N (next), and CTRL-P (previous).
|
||||
|
||||
By default, the possible completions are showed in a menu and the first
|
||||
completion is inserted into the text. This can be adjusted with 'completeopt'.
|
||||
|
||||
To get the current completion information, |complete_info()| can be used.
|
||||
Also see the 'infercase' option if you want to adjust the case of the match.
|
||||
|
||||
@@ -651,10 +657,11 @@ When completion is active you can use CTRL-E to stop it and go back to the
|
||||
originally typed text. The CTRL-E will not be inserted.
|
||||
|
||||
*complete_CTRL-Y*
|
||||
When the popup menu is displayed you can use CTRL-Y to stop completion and
|
||||
accept the currently selected entry. The CTRL-Y is not inserted. Typing a
|
||||
space, Enter, or some other unprintable character will leave completion mode
|
||||
and insert that typed character.
|
||||
When the popup menu is displayed, CTRL-Y stops completion and accepts the
|
||||
currently selected entry. Typing a space, Enter, or some other unprintable
|
||||
character will leave completion mode and insert that typed character. If you
|
||||
want to use <Enter> to accept a completion item, use this mapping: >vim
|
||||
inoremap <expr> <cr> pumvisible() ? '<c-y>' : '<cr>'
|
||||
|
||||
When the popup menu is displayed there are a few more special keys, see
|
||||
|popupmenu-keys|.
|
||||
@@ -998,6 +1005,25 @@ CTRL-X CTRL-V Guess what kind of item is in front of the cursor and
|
||||
completion, for example: >
|
||||
:imap <Tab> <C-X><C-V>
|
||||
|
||||
Completing contents from registers *compl-register-words*
|
||||
*i_CTRL-X_CTRL-R*
|
||||
CTRL-X CTRL-R Guess what kind of item is in front of the cursor from
|
||||
all registers and find the first match for it.
|
||||
Further use of CTRL-R (without CTRL-X) will insert the
|
||||
register content, see |i_CTRL-R|.
|
||||
'ignorecase' applies to the matching.
|
||||
|
||||
CTRL-N Search forwards for next match. This match replaces
|
||||
the previous one.
|
||||
|
||||
CTRL-P Search backwards for previous match. This match
|
||||
replaces the previous one.
|
||||
|
||||
CTRL-X CTRL-R Further use of CTRL-X CTRL-R will copy the line
|
||||
following the previous expansion in other contexts
|
||||
unless a double CTRL-X is used (e.g. this switches
|
||||
from completing register words to register contents).
|
||||
|
||||
User defined completion *compl-function*
|
||||
|
||||
Completion is done by a function that can be defined by the user with the
|
||||
@@ -1058,25 +1084,23 @@ CTRL-X s Locate the word in front of the cursor and find the
|
||||
previous one.
|
||||
|
||||
|
||||
Completing keywords from different sources *compl-generic*
|
||||
Completing from different sources *compl-generic*
|
||||
|
||||
*i_CTRL-N*
|
||||
CTRL-N Find next match for words that start with the
|
||||
keyword in front of the cursor, looking in places
|
||||
specified with the 'complete' option. The found
|
||||
keyword is inserted in front of the cursor.
|
||||
CTRL-N Find the next match for a word ending at the cursor,
|
||||
using the sources specified in the 'complete' option.
|
||||
All sources complete from keywords, except functions,
|
||||
which may complete from non-keyword. The matched
|
||||
text is inserted before the cursor.
|
||||
|
||||
*i_CTRL-P*
|
||||
CTRL-P Find previous match for words that start with the
|
||||
keyword in front of the cursor, looking in places
|
||||
specified with the 'complete' option. The found
|
||||
keyword is inserted in front of the cursor.
|
||||
CTRL-P Same as CTRL-N, but find the previous match.
|
||||
|
||||
CTRL-N Search forward for next matching keyword. This
|
||||
keyword replaces the previous matching keyword.
|
||||
CTRL-N Search forward through the matches and insert the
|
||||
next one.
|
||||
|
||||
CTRL-P Search backwards for next matching keyword. This
|
||||
keyword replaces the previous matching keyword.
|
||||
CTRL-P Search backward through the matches and insert the
|
||||
previous one.
|
||||
|
||||
CTRL-X CTRL-N or
|
||||
CTRL-X CTRL-P Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will
|
||||
@@ -1090,26 +1114,25 @@ Stop completion *compl-stop*
|
||||
CTRL-X CTRL-Z Stop completion without changing the text.
|
||||
|
||||
|
||||
AUTO-COMPLETION *compl-autocomplete*
|
||||
AUTOCOMPLETION *ins-autocompletion*
|
||||
|
||||
To get LSP-driven auto-completion, see |lsp-completion|. To get basic
|
||||
auto-completion without installing plugins or LSP, try this: >lua
|
||||
Vim can display a completion menu as you type, similar to using |i_CTRL-N|,
|
||||
but triggered automatically. See 'autocomplete'. The menu items are collected
|
||||
from the sources listed in the 'complete' option, in order.
|
||||
|
||||
A decaying timeout keeps Vim responsive. Sources earlier in the 'complete'
|
||||
list get more time (higher priority), but all sources receive at least a small
|
||||
time slice.
|
||||
|
||||
This mode is fully compatible with other completion modes. You can invoke
|
||||
any of them at any time by typing |CTRL-X|, which temporarily suspends
|
||||
autocompletion. To use |i_CTRL-N| or |i_CTRL-X_CTRL-N| specifically, press
|
||||
|CTRL-E| first to dismiss the popup menu (see |complete_CTRL-E|).
|
||||
|
||||
See also 'autocomplete', 'autocompletetimeout' and 'autocompletedelay'.
|
||||
|
||||
To get LSP-driven auto-completion, see |lsp-completion|.
|
||||
|
||||
local triggers = {'.'}
|
||||
vim.api.nvim_create_autocmd('InsertCharPre', {
|
||||
buffer = vim.api.nvim_get_current_buf(),
|
||||
callback = function()
|
||||
if vim.fn.pumvisible() == 1 or vim.fn.state('m') == 'm' then
|
||||
return
|
||||
end
|
||||
local char = vim.v.char
|
||||
if vim.list_contains(triggers, char) then
|
||||
local key = vim.keycode('<C-x><C-n>')
|
||||
vim.api.nvim_feedkeys(key, 'm', false)
|
||||
end
|
||||
end
|
||||
})
|
||||
<
|
||||
|
||||
FUNCTIONS FOR FINDING COMPLETIONS *complete-functions*
|
||||
|
||||
@@ -1162,6 +1185,9 @@ For example, the function can contain this: >
|
||||
let matches = ... list of words ...
|
||||
return {'words': matches, 'refresh': 'always'}
|
||||
<
|
||||
If looking for matches is time-consuming, |complete_check()| may be used to
|
||||
maintain responsiveness.
|
||||
|
||||
*complete-items*
|
||||
Each list item can either be a string or a Dictionary. When it is a string it
|
||||
is used as the completion. When it is a Dictionary it can contain these
|
||||
@@ -1296,6 +1322,7 @@ use all space available.
|
||||
The 'pumwidth' option can be used to set a minimum width. The default is 15
|
||||
characters.
|
||||
|
||||
*compl-states*
|
||||
There are three states:
|
||||
1. A complete match has been inserted, e.g., after using CTRL-N or CTRL-P.
|
||||
2. A cursor key has been used to select another match. The match was not
|
||||
@@ -1923,7 +1950,7 @@ These commands are used to start inserting text. You can end insert mode with
|
||||
<Esc>. See |mode-ins-repl| for the other special characters in Insert mode.
|
||||
The effect of [count] takes place after Insert mode is exited.
|
||||
|
||||
The following commands insert text, but stay in normal mode:
|
||||
The following |default-mappings| insert text, but stay in normal mode:
|
||||
|
||||
*]<Space>*
|
||||
]<Space> Insert an empty line below the cursor without leaving
|
||||
|
@@ -89,7 +89,7 @@ To uninstall Nvim:
|
||||
- Scoop (Windows): `scoop uninstall neovim`
|
||||
|
||||
==============================================================================
|
||||
Sponsor Vim/Nvim development *sponsor* *register*
|
||||
Sponsor Vim/Nvim development *sponsor*
|
||||
|
||||
Fixing bugs and adding new features takes a lot of time and effort. To show
|
||||
your appreciation for the work and motivate developers to continue working on
|
||||
@@ -605,7 +605,7 @@ status messages will only be used if an option is on: >
|
||||
command characters 'showcmd' on off
|
||||
cursor position 'ruler' off off
|
||||
|
||||
The current mode is "-- INSERT --" or "-- REPLACE --", see |'showmode'|. The
|
||||
The current mode is "-- INSERT --" or "-- REPLACE --", see 'showmode'. The
|
||||
command characters are those that you typed but were not used yet.
|
||||
|
||||
If you have a slow terminal you can switch off the status messages to speed
|
||||
@@ -711,5 +711,4 @@ Arbitrary code registered via |:UpdateRemotePlugins|, that runs in a separate
|
||||
process and communicates with Nvim via the |api|.
|
||||
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:et:sw=4:ft=help:norl:
|
||||
|
@@ -140,5 +140,4 @@ A job may be killed at any time with the |jobstop()| function:
|
||||
<
|
||||
Individual streams can be closed without killing the job, see |chanclose()|.
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
2079
runtime/doc/lsp.txt
2079
runtime/doc/lsp.txt
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user