mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
Compare commits
1505 Commits
v0.11.2
...
b4d21f141c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b4d21f141c | ||
![]() |
4f374bf938 | ||
![]() |
c4c69c5012 | ||
![]() |
a5e7ccc329 | ||
![]() |
28ab656122 | ||
![]() |
8a12a01466 | ||
![]() |
4cda52a5d1 | ||
![]() |
d8a8825679 | ||
![]() |
6888f65be1 | ||
![]() |
06df337617 | ||
![]() |
8fc1db043a | ||
![]() |
d4f789fd78 | ||
![]() |
3c601d02dc | ||
![]() |
c6bfc203f1 | ||
![]() |
77e3efecee | ||
![]() |
f311c96973 | ||
![]() |
582e0714b5 | ||
![]() |
6a330f893b | ||
![]() |
1b3abfa688 | ||
![]() |
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.
|
||||
-->
|
14
.github/scripts/env.ps1
vendored
14
.github/scripts/env.ps1
vendored
@@ -1,8 +1,16 @@
|
||||
# This script enables Developer Command Prompt
|
||||
# See https://github.com/microsoft/vswhere/wiki/Start-Developer-Command-Prompt#using-powershell
|
||||
$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||
if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) {
|
||||
& "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object {
|
||||
if ($env:BUILD_ARCH -eq "arm64") {
|
||||
$arch = "arm64"
|
||||
$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.arm64 -property installationPath
|
||||
} else {
|
||||
$arch = "x64"
|
||||
$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||
}
|
||||
|
||||
if ($installationPath) {
|
||||
& "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=$arch -no_logo && set" |
|
||||
ForEach-Object {
|
||||
$name, $value = $_ -split '=', 2
|
||||
"$name=$value" >> $env:GITHUB_ENV
|
||||
}
|
||||
|
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 }}
|
||||
|
19
.github/workflows/notes.md
vendored
19
.github/workflows/notes.md
vendored
@@ -2,21 +2,26 @@
|
||||
${NVIM_VERSION}
|
||||
```
|
||||
|
||||
## Release notes
|
||||
|
||||
- [Changelog](https://github.com/neovim/neovim/commit/${NVIM_COMMIT}) (fixes + features)
|
||||
- [News](./runtime/doc/news.txt) (`:help news` in Nvim)
|
||||
|
||||
## Install
|
||||
|
||||
### Windows
|
||||
|
||||
#### Zip
|
||||
|
||||
1. Download **nvim-win64.zip**
|
||||
1. Download **nvim-win64.zip** (or **nvim-win-arm64.zip** for ARM)
|
||||
2. Extract the zip
|
||||
3. Run `nvim.exe` on your CLI of choice
|
||||
3. Run `nvim.exe` in your terminal
|
||||
|
||||
#### MSI
|
||||
|
||||
1. Download **nvim-win64.msi**
|
||||
1. Download **nvim-win64.msi** (or **nvim-win-arm64.msi** for ARM)
|
||||
2. Run the MSI
|
||||
3. Run `nvim.exe` on your CLI of choice
|
||||
3. Run `nvim.exe` in your terminal
|
||||
|
||||
Note: On Windows "Server" you may need to [install vcruntime140.dll](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
|
||||
|
||||
@@ -36,7 +41,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 +59,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 +80,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
|
||||
|
56
.github/workflows/release.yml
vendored
56
.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,27 +132,44 @@ jobs:
|
||||
|
||||
windows:
|
||||
needs: setup
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- runner: windows-2022
|
||||
arch: x86_64
|
||||
archive_name: nvim-win64
|
||||
- runner: windows-11-arm
|
||||
arch: arm64
|
||||
archive_name: nvim-win-arm64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# Perform a full checkout #13471
|
||||
fetch-depth: 0
|
||||
- run: .github/scripts/env.ps1
|
||||
env:
|
||||
BUILD_ARCH: ${{ matrix.arch }}
|
||||
- name: Install Wix
|
||||
run: |
|
||||
Invoke-WebRequest -Uri "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip" -OutFile "wix314-binaries.zip"
|
||||
Expand-Archive -Path "wix314-binaries.zip" -DestinationPath "C:/wix"
|
||||
echo "C:\wix" >> $env:GITHUB_PATH
|
||||
- name: Build deps
|
||||
run: |
|
||||
cmake -S cmake.deps -B .deps -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}
|
||||
cmake --build .deps
|
||||
- name: build package
|
||||
- name: Build package
|
||||
run: |
|
||||
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}
|
||||
cmake --build build --target package
|
||||
- uses: actions/upload-artifact@v4
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nvim-win64
|
||||
name: nvim-win-${{ matrix.arch }}
|
||||
path: |
|
||||
build/nvim-win64.msi
|
||||
build/nvim-win64.zip
|
||||
build/${{ matrix.archive_name }}.zip
|
||||
build/${{ matrix.archive_name }}.msi
|
||||
retention-days: 1
|
||||
|
||||
publish:
|
||||
@@ -166,9 +183,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 +210,14 @@ 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 }}
|
||||
NVIM_COMMIT: ${{ github.sha }}
|
||||
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-win-x86_64/* nvim-win-arm64/*
|
||||
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-win-x86_64/* nvim-win-arm64/*
|
||||
|
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
|
||||
|
@@ -1,4 +1,4 @@
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|ARM64|aarch64)$")
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm64)
|
||||
endif()
|
||||
|
||||
@@ -27,9 +27,13 @@ set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md)
|
||||
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
set(CPACK_PACKAGE_FILE_NAME "nvim-win-arm64")
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME "nvim-win64")
|
||||
set(CPACK_GENERATOR ZIP WIX)
|
||||
endif()
|
||||
|
||||
set(CPACK_GENERATOR ZIP WIX)
|
||||
# WIX
|
||||
# CPACK_WIX_UPGRADE_GUID should be set, but should never change.
|
||||
# CPACK_WIX_PRODUCT_GUID should not be set (leave as default to auto-generate).
|
||||
|
@@ -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 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)
|
||||
return 0
|
||||
end
|
||||
|
||||
if s:cache_enabled == 0
|
||||
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
|
||||
@@ -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))
|
||||
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
|
||||
call system("del /S ".shellescape(a:fname,0))
|
||||
endif
|
||||
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,6 +237,7 @@ endfun
|
||||
" zip#Write: {{{2
|
||||
fun! zip#Write(fname)
|
||||
let dict = s:SetSaneOpts()
|
||||
let need_rename = 0
|
||||
defer s:RestoreOpts(dict)
|
||||
|
||||
" sanity checks
|
||||
@@ -242,10 +245,6 @@ fun! zip#Write(fname)
|
||||
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
|
||||
endif
|
||||
|
||||
let curdir= getcwd()
|
||||
let tmpdir= tempname()
|
||||
@@ -273,6 +272,11 @@ fun! zip#Write(fname)
|
||||
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')
|
||||
@@ -285,7 +289,8 @@ fun! zip#Write(fname)
|
||||
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')
|
||||
endif
|
||||
@@ -311,6 +316,9 @@ fun! zip#Write(fname)
|
||||
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
|
||||
|
||||
" ---------------------------------------------------------------------
|
||||
@@ -337,6 +344,9 @@ fun! zip#Extract()
|
||||
if fname =~ '/$'
|
||||
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!")
|
||||
@@ -368,7 +378,6 @@ fun! zip#Extract()
|
||||
else
|
||||
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:
|
3280
runtime/doc/api.txt
3280
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
@@ -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,
|
||||
@@ -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)
|
||||
" 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)
|
||||
" 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.
|
||||
" 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'),
|
||||
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: ")
|
||||
call prompt_setcallback(buf, function('OnSubmit'))
|
||||
call prompt_setprompt(buf, 'shell command: ')
|
||||
|
||||
" start accepting shell commands
|
||||
" 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
|
||||
@@ -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
|
||||
<
|
||||
|
||||
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,20 +91,19 @@ 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 = {}
|
||||
|
||||
M.check = function()
|
||||
@@ -111,6 +119,7 @@ with your plugin name: >lua
|
||||
end
|
||||
|
||||
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.
|
||||
@@ -377,7 +377,13 @@ also implicitly stops the block of ex-commands before it. E.g. >
|
||||
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:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user