mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Compare commits
482 Commits
marvim/ci-
...
v0.9.4
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d772f697a2 | ||
![]() |
cc398c5b06 | ||
![]() |
51ac490c01 | ||
![]() |
3257fdac36 | ||
![]() |
837f64f98a | ||
![]() |
4f6e4c5447 | ||
![]() |
eddead1cad | ||
![]() |
2bde3109b8 | ||
![]() |
e0d98bd25d | ||
![]() |
749ff7a342 | ||
![]() |
6809d3377c | ||
![]() |
00a0847675 | ||
![]() |
a0da8c3e69 | ||
![]() |
ce52639936 | ||
![]() |
bd042ef086 | ||
![]() |
1403779ae0 | ||
![]() |
49d7de8f5c | ||
![]() |
d5c16d1bfe | ||
![]() |
f5b43bf1f3 | ||
![]() |
e298c01cfb | ||
![]() |
ee8948f073 | ||
![]() |
9efc6f7c4d | ||
![]() |
b1891c5fea | ||
![]() |
0360ceffc9 | ||
![]() |
166c22f528 | ||
![]() |
2b2a20f4ea | ||
![]() |
b4f58d6745 | ||
![]() |
da4d59018d | ||
![]() |
e5ec72562d | ||
![]() |
00c3ffdb4b | ||
![]() |
c21ca9b87a | ||
![]() |
792b10d03e | ||
![]() |
c901472d67 | ||
![]() |
25ac45386c | ||
![]() |
5bf0873d86 | ||
![]() |
fd0ff7665c | ||
![]() |
b49cb1826a | ||
![]() |
aa5b5b434d | ||
![]() |
8063aa7cf6 | ||
![]() |
6156d3fdc9 | ||
![]() |
c16af962db | ||
![]() |
232a4eaef7 | ||
![]() |
b3b30dbaf7 | ||
![]() |
94246472e3 | ||
![]() |
a89c385f33 | ||
![]() |
926b8f9120 | ||
![]() |
1b8132880d | ||
![]() |
3f796c5410 | ||
![]() |
82e0a6028c | ||
![]() |
cb211e5746 | ||
![]() |
28f600337f | ||
![]() |
26c6d78a0c | ||
![]() |
249e930eaf | ||
![]() |
7fd12dabcc | ||
![]() |
3a5b46e6bb | ||
![]() |
68ae7ea529 | ||
![]() |
3f5f6d412b | ||
![]() |
aa04090e92 | ||
![]() |
cdb8c46253 | ||
![]() |
f0898d438e | ||
![]() |
d1813f73b8 | ||
![]() |
9df72d3f9f | ||
![]() |
cd6536c140 | ||
![]() |
d1cce10702 | ||
![]() |
fc8d1f7c7e | ||
![]() |
f0b1e46f91 | ||
![]() |
57aeacc344 | ||
![]() |
5f8676c268 | ||
![]() |
c7b316f71a | ||
![]() |
64160bac5b | ||
![]() |
51edadcaeb | ||
![]() |
284c2e0124 | ||
![]() |
e20f3a815a | ||
![]() |
fe869a8ce2 | ||
![]() |
3a13777289 | ||
![]() |
4728f2d2f9 | ||
![]() |
6490d937b2 | ||
![]() |
bee2ee211c | ||
![]() |
876cb05e2a | ||
![]() |
ed626d2f8f | ||
![]() |
c23bff6603 | ||
![]() |
f54806fd7f | ||
![]() |
3c5339ba36 | ||
![]() |
40a7228dcc | ||
![]() |
a285a0b36d | ||
![]() |
3ada031231 | ||
![]() |
be14ead380 | ||
![]() |
fec20ce15c | ||
![]() |
033059e781 | ||
![]() |
32de3f98ed | ||
![]() |
a3c963adfc | ||
![]() |
e3389c1533 | ||
![]() |
f5e6f592b6 | ||
![]() |
5ef7bc50cc | ||
![]() |
eacd5ca6b8 | ||
![]() |
a6226aea6c | ||
![]() |
8ec03bbc8b | ||
![]() |
3cca5449ac | ||
![]() |
1fc72d3e62 | ||
![]() |
2aa88ee86a | ||
![]() |
2ac6405e80 | ||
![]() |
96dc2d559b | ||
![]() |
40361818c1 | ||
![]() |
11cb728c35 | ||
![]() |
62ae5f373a | ||
![]() |
9f928902c7 | ||
![]() |
b30896bbaf | ||
![]() |
13c368eca5 | ||
![]() |
bb847a8b55 | ||
![]() |
b353c27338 | ||
![]() |
46fc9d547c | ||
![]() |
c083d7ac78 | ||
![]() |
016b883def | ||
![]() |
2a9af09187 | ||
![]() |
167499d36f | ||
![]() |
35bc5d1af3 | ||
![]() |
7854874367 | ||
![]() |
4d6d4f8fbe | ||
![]() |
021bed5ac2 | ||
![]() |
931bcc8081 | ||
![]() |
392e0b56f0 | ||
![]() |
403d17b5b7 | ||
![]() |
b82ba25ba5 | ||
![]() |
52669b5c69 | ||
![]() |
211db74a31 | ||
![]() |
79067685ab | ||
![]() |
1cd08f242f | ||
![]() |
ac2dff64a5 | ||
![]() |
bedd4bd746 | ||
![]() |
06ec1a49d7 | ||
![]() |
df63474930 | ||
![]() |
5e6c8b3385 | ||
![]() |
9d1c8bc5c0 | ||
![]() |
e977f3dd4f | ||
![]() |
060886e16c | ||
![]() |
241d649c23 | ||
![]() |
f237c92076 | ||
![]() |
90b1a3250a | ||
![]() |
ff689ed1a9 | ||
![]() |
f33d49a7a7 | ||
![]() |
d0a6c1437d | ||
![]() |
9f6fc24bcb | ||
![]() |
c03d38c51d | ||
![]() |
bde56f4e37 | ||
![]() |
1fdb41969f | ||
![]() |
1e905c52ca | ||
![]() |
b31b01cac2 | ||
![]() |
46301281f7 | ||
![]() |
d6733abc69 | ||
![]() |
42a735e524 | ||
![]() |
ada9443999 | ||
![]() |
69f11f6d26 | ||
![]() |
badb6f4bc3 | ||
![]() |
0afec352da | ||
![]() |
1da1e5a4f3 | ||
![]() |
dfed74188d | ||
![]() |
d1a7aaa7f2 | ||
![]() |
76bbfb3cfd | ||
![]() |
11e90126ba | ||
![]() |
aefacff567 | ||
![]() |
cba4362d85 | ||
![]() |
8dd4a2bdd1 | ||
![]() |
dc2860d821 | ||
![]() |
78b39d510a | ||
![]() |
16e690d595 | ||
![]() |
740cb0c7dd | ||
![]() |
48d5eaffcd | ||
![]() |
af1da51d11 | ||
![]() |
e2d14926d7 | ||
![]() |
a3889e743f | ||
![]() |
8ac7491685 | ||
![]() |
776a9b59b6 | ||
![]() |
e8ff921ed3 | ||
![]() |
d82f386201 | ||
![]() |
cf4b89f16b | ||
![]() |
953904c006 | ||
![]() |
c0c6294123 | ||
![]() |
b0abe426d6 | ||
![]() |
115fe762b4 | ||
![]() |
f0e4d284fd | ||
![]() |
65d9407835 | ||
![]() |
d3ac249806 | ||
![]() |
344bcb5f30 | ||
![]() |
0bc272d0ea | ||
![]() |
7253cb3905 | ||
![]() |
9fdaecba90 | ||
![]() |
6808f47ec5 | ||
![]() |
e9030d109e | ||
![]() |
541439b4ab | ||
![]() |
160bdee527 | ||
![]() |
84086283ac | ||
![]() |
5174ed6735 | ||
![]() |
f36433f83a | ||
![]() |
3fc024f238 | ||
![]() |
1234861183 | ||
![]() |
8fe351b674 | ||
![]() |
617c6014ea | ||
![]() |
041bc87333 | ||
![]() |
08ae485984 | ||
![]() |
3a6235cb81 | ||
![]() |
38af92ce39 | ||
![]() |
04f6463ee2 | ||
![]() |
1f9c2cfa91 | ||
![]() |
657072fc62 | ||
![]() |
f088b26ab1 | ||
![]() |
072d0b796e | ||
![]() |
4be7f29af6 | ||
![]() |
914717aa8b | ||
![]() |
e2ceb8dd47 | ||
![]() |
a830373860 | ||
![]() |
81290cda02 | ||
![]() |
f81b85a0fa | ||
![]() |
c8bd1d131f | ||
![]() |
213a5204ee | ||
![]() |
54294140d7 | ||
![]() |
e4945e69f7 | ||
![]() |
74c8878e9f | ||
![]() |
b9a513ae11 | ||
![]() |
d9a76056bb | ||
![]() |
6ed84f8571 | ||
![]() |
0f121fea81 | ||
![]() |
db41f29b7c | ||
![]() |
4c8376a876 | ||
![]() |
3d06b6c6af | ||
![]() |
abed0acf56 | ||
![]() |
2f9ee5eb16 | ||
![]() |
4dafd5341a | ||
![]() |
adea8885c4 | ||
![]() |
135cdd5ac0 | ||
![]() |
d182c1b526 | ||
![]() |
3dae99d86a | ||
![]() |
470017c9a8 | ||
![]() |
5825aec7ae | ||
![]() |
3904bf4906 | ||
![]() |
27c3e1d18f | ||
![]() |
0bbd78aef1 | ||
![]() |
db33f17618 | ||
![]() |
7e7fc4885f | ||
![]() |
55373061ab | ||
![]() |
79c8df7e97 | ||
![]() |
6937075304 | ||
![]() |
d7212c10e2 | ||
![]() |
af1f4c7122 | ||
![]() |
06d0985722 | ||
![]() |
b9e380fed9 | ||
![]() |
d964aba20d | ||
![]() |
4892db22e2 | ||
![]() |
7ef651beaf | ||
![]() |
0db9169a52 | ||
![]() |
9078db9bbb | ||
![]() |
0e39b334c0 | ||
![]() |
f9a615fb21 | ||
![]() |
022b5ba45d | ||
![]() |
56c35faf8b | ||
![]() |
06d137681e | ||
![]() |
4b79441b14 | ||
![]() |
2113b9e4b0 | ||
![]() |
6edd802840 | ||
![]() |
1513666203 | ||
![]() |
afdb5fa3cd | ||
![]() |
cd73e54c42 | ||
![]() |
0a954f41c4 | ||
![]() |
8463161daa | ||
![]() |
72209f4bf7 | ||
![]() |
2833230791 | ||
![]() |
09f97ff9a8 | ||
![]() |
b257480955 | ||
![]() |
a4097be568 | ||
![]() |
433ccdfc79 | ||
![]() |
126a757c55 | ||
![]() |
65fc17b343 | ||
![]() |
954cc51226 | ||
![]() |
18fe3a6a44 | ||
![]() |
7d4bba7aa7 | ||
![]() |
c0137e711b | ||
![]() |
a2bfe4e524 | ||
![]() |
a1007597ca | ||
![]() |
b1f5be5338 | ||
![]() |
edf2a5aa25 | ||
![]() |
e953f29c9b | ||
![]() |
eaacdd059e | ||
![]() |
b5a66b1830 | ||
![]() |
7556850724 | ||
![]() |
68f967ce47 | ||
![]() |
84542fc97f | ||
![]() |
a090be56bd | ||
![]() |
3591252cc8 | ||
![]() |
ea5ebe509b | ||
![]() |
fdf33d9b00 | ||
![]() |
86a1e79ee2 | ||
![]() |
9e603ec3e1 | ||
![]() |
624c25a70a | ||
![]() |
b6ddf72bf1 | ||
![]() |
a532f7d527 | ||
![]() |
d0d9662ea1 | ||
![]() |
d34d987070 | ||
![]() |
c75cf9b64a | ||
![]() |
ceba495e88 | ||
![]() |
55138cdd8f | ||
![]() |
cbe9351f8b | ||
![]() |
8ace26ade7 | ||
![]() |
2430e96da5 | ||
![]() |
2625d84577 | ||
![]() |
a01f8de1f0 | ||
![]() |
c8d6d14f71 | ||
![]() |
2be8c29406 | ||
![]() |
d5ac60c093 | ||
![]() |
3ea6c5e7ba | ||
![]() |
59e63b455b | ||
![]() |
87c44c7a0b | ||
![]() |
626e2277a9 | ||
![]() |
f3c7182482 | ||
![]() |
6f7e5ce006 | ||
![]() |
ae7db749b5 | ||
![]() |
9b90f5fa28 | ||
![]() |
e019371554 | ||
![]() |
35997026a2 | ||
![]() |
4e0cfe3805 | ||
![]() |
31a009c883 | ||
![]() |
06bee06ee5 | ||
![]() |
9652f7c4c9 | ||
![]() |
17bdaeb79e | ||
![]() |
4d30f34a37 | ||
![]() |
59ee42d05e | ||
![]() |
1a104253df | ||
![]() |
ac93bd3817 | ||
![]() |
c0c95bc823 | ||
![]() |
152c07249e | ||
![]() |
8f2b0d9b5d | ||
![]() |
bdb7c180b7 | ||
![]() |
965f817ade | ||
![]() |
9ea3a9c15b | ||
![]() |
c3d11208bc | ||
![]() |
fe261706a2 | ||
![]() |
592e4459fa | ||
![]() |
1b09bcef52 | ||
![]() |
c464df84f7 | ||
![]() |
13d8cca951 | ||
![]() |
9edddceb18 | ||
![]() |
7c48810397 | ||
![]() |
fb56d2a452 | ||
![]() |
106695d47e | ||
![]() |
56e0b425ea | ||
![]() |
017afa2fcf | ||
![]() |
61351adee8 | ||
![]() |
7dfddb3e43 | ||
![]() |
5fbe8409b5 | ||
![]() |
4d1d9472fe | ||
![]() |
bbf600b7b5 | ||
![]() |
76dd0f81b0 | ||
![]() |
607237a20a | ||
![]() |
5267e7b07a | ||
![]() |
49092de818 | ||
![]() |
20f5f4e916 | ||
![]() |
5b158b9375 | ||
![]() |
c693df02b3 | ||
![]() |
beaa29d70e | ||
![]() |
11a0fc9644 | ||
![]() |
756b74758d | ||
![]() |
3563f4b623 | ||
![]() |
f5cf033314 | ||
![]() |
7a9624f035 | ||
![]() |
5c30930fec | ||
![]() |
3754d833ec | ||
![]() |
b8b1221e58 | ||
![]() |
f77b2740ee | ||
![]() |
98a90abca9 | ||
![]() |
fc2822a819 | ||
![]() |
b8d0a2d2b2 | ||
![]() |
e81b2eb94a | ||
![]() |
5c2f442a74 | ||
![]() |
fb73bfd667 | ||
![]() |
6a8d1bb90b | ||
![]() |
feb8134b43 | ||
![]() |
d926f92ba1 | ||
![]() |
66a196c951 | ||
![]() |
d366a1f8ed | ||
![]() |
53d29a8b62 | ||
![]() |
26aa39f80c | ||
![]() |
a8c62d3024 | ||
![]() |
c236e674ce | ||
![]() |
0874a14dcf | ||
![]() |
4bc50de152 | ||
![]() |
a7578a873c | ||
![]() |
af6669cd35 | ||
![]() |
f24449d35c | ||
![]() |
0c8e2d128e | ||
![]() |
f991ddd1ab | ||
![]() |
a977c8b5fe | ||
![]() |
f5bf29a0ad | ||
![]() |
deec5e6e2a | ||
![]() |
d6deffad57 | ||
![]() |
d7b720f3d8 | ||
![]() |
39ae0a0b7a | ||
![]() |
f960f2621d | ||
![]() |
e937b9a9c7 | ||
![]() |
c52085997b | ||
![]() |
127a483142 | ||
![]() |
2363d44d5a | ||
![]() |
5cb6c44e30 | ||
![]() |
df3982e704 | ||
![]() |
30cfd28257 | ||
![]() |
1085e91876 | ||
![]() |
c0845343b6 | ||
![]() |
a99d5d17d5 | ||
![]() |
a77a8a9934 | ||
![]() |
6b32fe96b0 | ||
![]() |
6ba14ff182 | ||
![]() |
6bd73ed2d9 | ||
![]() |
b91278c4fa | ||
![]() |
b2a43b5287 | ||
![]() |
400bf2851a | ||
![]() |
a5d8024b24 | ||
![]() |
2d3c825ada | ||
![]() |
ef7513c87f | ||
![]() |
9cb2f2fc31 | ||
![]() |
a41930bcf0 | ||
![]() |
fa5fe845cc | ||
![]() |
30581744e4 | ||
![]() |
535d8553c4 | ||
![]() |
40ef3b2bd4 | ||
![]() |
54f930f4e3 | ||
![]() |
37a44f3247 | ||
![]() |
470aa2dbf9 | ||
![]() |
ba198bd7cc | ||
![]() |
96de6bbaad | ||
![]() |
54c6dfa009 | ||
![]() |
8e2af977b1 | ||
![]() |
fc545cb008 | ||
![]() |
42199afc14 | ||
![]() |
c9f1e6837a | ||
![]() |
1103a4c2c6 | ||
![]() |
79ee63bc36 | ||
![]() |
6b88a9555c | ||
![]() |
9066b68832 | ||
![]() |
f92d99f0d9 | ||
![]() |
fee9452b77 | ||
![]() |
69d4e64c60 | ||
![]() |
d24bdc4999 | ||
![]() |
6625fd8766 | ||
![]() |
30627250bd | ||
![]() |
232fdf2ccd | ||
![]() |
46e875a8a2 | ||
![]() |
4b728cc3d7 | ||
![]() |
2479c63d4a | ||
![]() |
f64518ed9c | ||
![]() |
eb9a95ea8e | ||
![]() |
2e819d3707 | ||
![]() |
911aabeaeb | ||
![]() |
763164cd9c | ||
![]() |
702621f058 | ||
![]() |
e50ce4ee3f | ||
![]() |
14e3936871 | ||
![]() |
00a1a9327e | ||
![]() |
7b64dcb30e | ||
![]() |
2658511d77 | ||
![]() |
974bd47067 | ||
![]() |
3cde3ae9b5 | ||
![]() |
4758f8ea7a | ||
![]() |
2812d6a6dd | ||
![]() |
8146fe86f9 | ||
![]() |
ae797c08e9 | ||
![]() |
8aeb262b1b | ||
![]() |
76631ee593 | ||
![]() |
ebd091f39e | ||
![]() |
756dd439db | ||
![]() |
e542e07c01 | ||
![]() |
d9ceb213d9 | ||
![]() |
92ffc44ce7 | ||
![]() |
19bc7456b8 | ||
![]() |
7a3dbde15c | ||
![]() |
513c881900 | ||
![]() |
eced07e6e3 | ||
![]() |
5f263789e0 | ||
![]() |
4db8c7d570 | ||
![]() |
67dc341aa0 | ||
![]() |
e2ab8f78c4 | ||
![]() |
07cba9e90a | ||
![]() |
f073f6248b | ||
![]() |
2399f4a539 | ||
![]() |
060fa561f7 | ||
![]() |
13b21bec0a |
@@ -9,12 +9,11 @@ freebsd_task:
|
|||||||
image_family: freebsd-13-1
|
image_family: freebsd-13-1
|
||||||
timeout_in: 30m
|
timeout_in: 30m
|
||||||
install_script:
|
install_script:
|
||||||
- pkg update -f
|
|
||||||
- pkg install -y cmake gmake ninja pkgconf unzip wget gettext python libffi git
|
- pkg install -y cmake gmake ninja pkgconf unzip wget gettext python libffi git
|
||||||
build_deps_script:
|
build_deps_script:
|
||||||
- gmake deps
|
- gmake deps
|
||||||
build_script:
|
build_script:
|
||||||
- gmake nvim
|
- gmake CMAKE_EXTRA_FLAGS="-DCI_BUILD=ON" nvim
|
||||||
workaround_script:
|
workaround_script:
|
||||||
# Run tests as user "cirrus" instead of root. This is required for the
|
# Run tests as user "cirrus" instead of root. This is required for the
|
||||||
# permission-related tests to work correctly.
|
# permission-related tests to work correctly.
|
||||||
|
6
.github/actions/cache/action.yml
vendored
6
.github/actions/cache/action.yml
vendored
@@ -10,6 +10,10 @@ runs:
|
|||||||
run: echo "CACHE_KEY=$CACHE_KEY-${{ join(matrix.*, '-') }}" >> $GITHUB_ENV
|
run: echo "CACHE_KEY=$CACHE_KEY-${{ join(matrix.*, '-') }}" >> $GITHUB_ENV
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
- id: image
|
||||||
|
run: echo "version=$ImageVersion" >> $GITHUB_OUTPUT
|
||||||
|
shell: bash
|
||||||
|
|
||||||
# Avoid using '**/CMakeLists.txt' (or any pattern starting with '**/') even
|
# Avoid using '**/CMakeLists.txt' (or any pattern starting with '**/') even
|
||||||
# if it makes the expression below simpler. hashFiles() has a timer that
|
# if it makes the expression below simpler. hashFiles() has a timer that
|
||||||
# will fail the job if it times out, which can happen if there are too many
|
# will fail the job if it times out, which can happen if there are too many
|
||||||
@@ -17,6 +21,6 @@ runs:
|
|||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: .deps
|
path: .deps
|
||||||
key: ${{ env.CACHE_KEY }}-${{ hashFiles('cmake**', 'ci/**',
|
key: ${{ env.CACHE_KEY }}-${{ steps.image.outputs.version }}-${{ hashFiles('cmake**',
|
||||||
'.github/workflows/test.yml', 'CMakeLists.txt',
|
'.github/workflows/test.yml', 'CMakeLists.txt',
|
||||||
'runtime/CMakeLists.txt', 'src/nvim/**/CMakeLists.txt') }}
|
'runtime/CMakeLists.txt', 'src/nvim/**/CMakeLists.txt') }}
|
||||||
|
29
.github/scripts/build_universal_macos.sh
vendored
29
.github/scripts/build_universal_macos.sh
vendored
@@ -1,36 +1,13 @@
|
|||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
echo "Provision universal libintl"
|
|
||||||
GETTEXT_PREFIX="$(brew --prefix gettext)"
|
|
||||||
printf 'GETTEXT_PREFIX=%s\n' "$GETTEXT_PREFIX" >> $GITHUB_ENV
|
|
||||||
bottle_tag="arm64_big_sur"
|
|
||||||
brew fetch --bottle-tag="$bottle_tag" gettext
|
|
||||||
cd "$(mktemp -d)"
|
|
||||||
tar xf "$(brew --cache)"/**/*gettext*${bottle_tag}*.tar.gz
|
|
||||||
lipo gettext/*/lib/libintl.a "${GETTEXT_PREFIX}/lib/libintl.a" -create -output libintl.a
|
|
||||||
mv -f libintl.a /usr/local/lib/
|
|
||||||
|
|
||||||
echo "Ensure static linkage to libintl"
|
|
||||||
# We're about to mangle `gettext`, so let's remove any potentially broken
|
|
||||||
# installs (e.g. curl, git) as those could interfere with our build.
|
|
||||||
brew uninstall $(brew uses --installed --recursive gettext)
|
|
||||||
brew unlink gettext
|
|
||||||
ln -sf "$(brew --prefix)/opt/$(readlink "${GETTEXT_PREFIX}")/bin"/* /usr/local/bin/
|
|
||||||
ln -sf "$(brew --prefix)/opt/$(readlink "${GETTEXT_PREFIX}")/include"/* /usr/local/include/
|
|
||||||
rm -f "$GETTEXT_PREFIX"
|
|
||||||
|
|
||||||
echo "Build release"
|
|
||||||
cd "$GITHUB_WORKSPACE"
|
|
||||||
MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -f1 -d.)"
|
MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -f1 -d.)"
|
||||||
export MACOSX_DEPLOYMENT_TARGET
|
export MACOSX_DEPLOYMENT_TARGET
|
||||||
cmake -S cmake.deps -B .deps -G Ninja -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64
|
cmake -S cmake.deps -B .deps -G Ninja -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64
|
||||||
cmake --build .deps
|
cmake --build .deps
|
||||||
cmake -B build -G Ninja -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 -D CI_BUILD=OFF
|
cmake -B build -G Ninja -D CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} -D CMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64
|
||||||
cmake --build build
|
cmake --build build
|
||||||
cmake --install build --prefix build/release/nvim-macos
|
|
||||||
cd build
|
|
||||||
# Make sure we build everything for M1 as well
|
# Make sure we build everything for M1 as well
|
||||||
for macho in bin/* lib/nvim/parser/*.so; do
|
for macho in build/bin/* build/lib/nvim/parser/*.so; do
|
||||||
lipo -info "$macho" | grep -q arm64 || exit 1
|
lipo -info "$macho" | grep -q arm64 || exit 1
|
||||||
done
|
done
|
||||||
cpack -C "$NVIM_BUILD_TYPE"
|
cpack --config build/CPackConfig.cmake
|
||||||
|
55
.github/scripts/close_unresponsive.js
vendored
Normal file
55
.github/scripts/close_unresponsive.js
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
function labeledEvent(data) {
|
||||||
|
return data.event === "labeled" && data.label.name === "needs:response";
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberOfDaysLimit = 30;
|
||||||
|
const close_message = `This has been closed since a request for information has \
|
||||||
|
not been answered for ${numberOfDaysLimit} days. It can be reopened when the \
|
||||||
|
requested information is provided.`;
|
||||||
|
|
||||||
|
module.exports = async ({ github, context }) => {
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
|
||||||
|
const issues = await github.rest.issues.listForRepo({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
labels: "needs:response",
|
||||||
|
});
|
||||||
|
const numbers = issues.data.map((e) => e.number);
|
||||||
|
|
||||||
|
for (const number of numbers) {
|
||||||
|
const events = await github.paginate(
|
||||||
|
github.rest.issues.listEventsForTimeline,
|
||||||
|
{
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
issue_number: number,
|
||||||
|
},
|
||||||
|
(response) => response.data.filter(labeledEvent)
|
||||||
|
);
|
||||||
|
|
||||||
|
const latest_response_label = events[events.length - 1];
|
||||||
|
|
||||||
|
const created_at = new Date(latest_response_label.created_at);
|
||||||
|
const now = new Date();
|
||||||
|
const diff = now - created_at;
|
||||||
|
const diffDays = diff / (1000 * 60 * 60 * 24);
|
||||||
|
|
||||||
|
if (diffDays > numberOfDaysLimit) {
|
||||||
|
github.rest.issues.update({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
issue_number: number,
|
||||||
|
state: "closed",
|
||||||
|
});
|
||||||
|
|
||||||
|
github.rest.issues.createComment({
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
issue_number: number,
|
||||||
|
body: close_message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
8
.github/scripts/remove-reviewers.js
vendored
8
.github/scripts/remove-reviewers.js
vendored
@@ -2,17 +2,15 @@ module.exports = async ({github, context}) => {
|
|||||||
const requestedReviewers = await github.rest.pulls.listRequestedReviewers({
|
const requestedReviewers = await github.rest.pulls.listRequestedReviewers({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
pull_number: context.issue.number
|
pull_number: context.issue.number,
|
||||||
});
|
});
|
||||||
|
|
||||||
const reviewers = requestedReviewers.data.users.map(e => e.login)
|
const reviewers = requestedReviewers.data.users.map((e) => e.login);
|
||||||
const team_reviewers = requestedReviewers.data.teams.map(e => e.name);
|
|
||||||
|
|
||||||
github.rest.pulls.removeRequestedReviewers({
|
github.rest.pulls.removeRequestedReviewers({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
pull_number: context.issue.number,
|
pull_number: context.issue.number,
|
||||||
reviewers: reviewers,
|
reviewers: reviewers,
|
||||||
team_reviewers: team_reviewers
|
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
114
.github/scripts/reviews.js
vendored
114
.github/scripts/reviews.js
vendored
@@ -2,101 +2,113 @@ module.exports = async ({github, context}) => {
|
|||||||
const pr_data = await github.rest.pulls.get({
|
const pr_data = await github.rest.pulls.get({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
pull_number: context.issue.number
|
pull_number: context.issue.number,
|
||||||
})
|
});
|
||||||
const labels = pr_data.data.labels.map(e => e.name)
|
const labels = pr_data.data.labels.map((e) => e.name);
|
||||||
|
const reviewers = new Set();
|
||||||
|
|
||||||
const reviewers = new Set()
|
if (labels.includes("api")) {
|
||||||
const team_reviewers = new Array()
|
reviewers.add("bfredl");
|
||||||
if (labels.includes('api')) {
|
reviewers.add("famiu");
|
||||||
reviewers.add("bfredl")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('build')) {
|
if (labels.includes("build")) {
|
||||||
team_reviewers.push('ci');
|
reviewers.add("dundargoc");
|
||||||
|
reviewers.add("jamessan");
|
||||||
|
reviewers.add("justinmk");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('ci')) {
|
if (labels.includes("ci")) {
|
||||||
team_reviewers.push('ci');
|
reviewers.add("dundargoc");
|
||||||
|
reviewers.add("jamessan");
|
||||||
|
reviewers.add("justinmk");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('column')) {
|
if (labels.includes("column")) {
|
||||||
reviewers.add("lewis6991")
|
reviewers.add("lewis6991");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('dependencies')) {
|
if (labels.includes("dependencies")) {
|
||||||
reviewers.add("jamessan")
|
reviewers.add("jamessan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('diagnostic')) {
|
if (labels.includes("diagnostic")) {
|
||||||
reviewers.add("gpanders")
|
reviewers.add("gpanders");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('diff')) {
|
if (labels.includes("diff")) {
|
||||||
reviewers.add("lewis6991")
|
reviewers.add("lewis6991");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('distribution')) {
|
if (labels.includes("distribution")) {
|
||||||
reviewers.add("jamessan")
|
reviewers.add("jamessan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('documentation')) {
|
if (labels.includes("documentation")) {
|
||||||
reviewers.add("clason")
|
reviewers.add("clason");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('extmarks')) {
|
if (labels.includes("extmarks")) {
|
||||||
reviewers.add("bfredl")
|
reviewers.add("bfredl");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('filetype')) {
|
if (labels.includes("filetype")) {
|
||||||
reviewers.add("clason")
|
reviewers.add("clason");
|
||||||
reviewers.add("gpanders")
|
reviewers.add("gpanders");
|
||||||
reviewers.add("smjonas")
|
reviewers.add("smjonas");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('lsp')) {
|
if (labels.includes("lsp")) {
|
||||||
team_reviewers.push('lsp');
|
reviewers.add("folke");
|
||||||
|
reviewers.add("glepnir");
|
||||||
|
reviewers.add("mfussenegger");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('platform:nix')) {
|
if (labels.includes("platform:nix")) {
|
||||||
reviewers.add("teto")
|
reviewers.add("teto");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('project-management')) {
|
if (labels.includes("project-management")) {
|
||||||
reviewers.add("bfredl")
|
reviewers.add("bfredl");
|
||||||
reviewers.add("justinmk")
|
reviewers.add("justinmk");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('test')) {
|
if (labels.includes("statusline")) {
|
||||||
reviewers.add("justinmk")
|
reviewers.add("famiu");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('treesitter')) {
|
if (labels.includes("test")) {
|
||||||
team_reviewers.push('treesitter');
|
reviewers.add("justinmk");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('typo')) {
|
if (labels.includes("treesitter")) {
|
||||||
reviewers.add("dundargoc")
|
reviewers.add("bfredl");
|
||||||
|
reviewers.add("clason");
|
||||||
|
reviewers.add("lewis6991");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('ui')) {
|
if (labels.includes("typo")) {
|
||||||
reviewers.add("bfredl")
|
reviewers.add("dundargoc");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes('vim-patch')) {
|
if (labels.includes("ui")) {
|
||||||
reviewers.add("seandewar")
|
reviewers.add("bfredl");
|
||||||
reviewers.add("zeertzjq")
|
reviewers.add("famiu");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (labels.includes("vim-patch")) {
|
||||||
|
reviewers.add("seandewar");
|
||||||
|
reviewers.add("zeertzjq");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove person that opened the PR since they can't review themselves
|
// Remove person that opened the PR since they can't review themselves
|
||||||
const pr_opener = pr_data.data.user.login
|
const pr_opener = pr_data.data.user.login;
|
||||||
reviewers.delete(pr_opener)
|
reviewers.delete(pr_opener);
|
||||||
|
|
||||||
github.rest.pulls.requestReviewers({
|
github.rest.pulls.requestReviewers({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
pull_number: context.issue.number,
|
pull_number: context.issue.number,
|
||||||
reviewers: Array.from(reviewers),
|
reviewers: Array.from(reviewers),
|
||||||
team_reviewers: team_reviewers
|
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
1
.github/workflows/add-reviewers.yml
vendored
1
.github/workflows/add-reviewers.yml
vendored
@@ -13,7 +13,6 @@ jobs:
|
|||||||
- name: 'Request reviewers'
|
- name: 'Request reviewers'
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v6
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.TEAM_REVIEW }}
|
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/reviews.js')
|
const script = require('./.github/scripts/reviews.js')
|
||||||
await script({github, context})
|
await script({github, context})
|
||||||
|
18
.github/workflows/api-docs-check.yml
vendored
18
.github/workflows/api-docs-check.yml
vendored
@@ -1,18 +0,0 @@
|
|||||||
name: Missing API docs
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches-ignore:
|
|
||||||
- 'marvim/api-doc-update**'
|
|
||||||
paths:
|
|
||||||
- 'src/nvim/api/*.[ch]'
|
|
||||||
- 'runtime/lua/**.lua'
|
|
||||||
- 'runtime/doc/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-regen-api-docs:
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
pull-requests: write
|
|
||||||
uses: ./.github/workflows/api-docs.yml
|
|
||||||
with:
|
|
||||||
check_only: true
|
|
42
.github/workflows/api-docs.yml
vendored
42
.github/workflows/api-docs.yml
vendored
@@ -1,23 +1,11 @@
|
|||||||
# Autogenerate the API docs on new commit to important branches
|
# Check if any PR needs to run the autogenerate script
|
||||||
# Also work as a check for PR's to not forget committing their doc changes
|
|
||||||
# called from api-docs-check.yml
|
|
||||||
name: Autogenerate API docs
|
name: Autogenerate API docs
|
||||||
on:
|
on:
|
||||||
push:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'src/nvim/api/*.[ch]'
|
- 'src/nvim/api/*.[ch]'
|
||||||
- 'runtime/lua/**.lua'
|
- 'runtime/lua/**.lua'
|
||||||
- 'runtime/doc/**'
|
- 'runtime/doc/**'
|
||||||
branches:
|
|
||||||
- 'master'
|
|
||||||
- 'release-[0-9]+.[0-9]+'
|
|
||||||
workflow_dispatch:
|
|
||||||
workflow_call:
|
|
||||||
inputs:
|
|
||||||
check_only:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
required: false
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
regen-api-docs:
|
regen-api-docs:
|
||||||
@@ -25,50 +13,26 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: rhysd/action-setup-vim@v1
|
- uses: rhysd/action-setup-vim@v1
|
||||||
with:
|
with:
|
||||||
neovim: true
|
neovim: true
|
||||||
version: nightly
|
version: nightly
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
# Fetch depth 0 is required if called through workflow_call. In order
|
|
||||||
# to create a PR we need to access other branches, which requires a
|
|
||||||
# full clone.
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y doxygen python3 python3-msgpack
|
sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y doxygen python3 python3-msgpack
|
||||||
|
|
||||||
- name: Set up git config
|
|
||||||
run: |
|
|
||||||
git config --global user.name 'marvim'
|
|
||||||
git config --global user.email 'marvim@users.noreply.github.com'
|
|
||||||
|
|
||||||
- run: printf 'DOC_BRANCH=marvim/api-doc-update/%s\n' ${GITHUB_REF#refs/heads/} >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Generate docs
|
- name: Generate docs
|
||||||
id: docs
|
id: docs
|
||||||
run: |
|
run: |
|
||||||
git checkout -b ${DOC_BRANCH}
|
|
||||||
python3 scripts/gen_vimdoc.py
|
python3 scripts/gen_vimdoc.py
|
||||||
printf 'UPDATED_DOCS=%s\n' $([ -z "$(git diff)" ]; echo $?) >> $GITHUB_OUTPUT
|
printf 'UPDATED_DOCS=%s\n' $([ -z "$(git diff)" ]; echo $?) >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: FAIL, PR has not committed doc changes
|
- name: FAIL, PR has not committed doc changes
|
||||||
if: ${{ steps.docs.outputs.UPDATED_DOCS != 0 && inputs.check_only }}
|
if: ${{ steps.docs.outputs.UPDATED_DOCS != 0 }}
|
||||||
run: |
|
run: |
|
||||||
echo "Job failed, run ./scripts/gen_vimdoc.py and commit your doc changes"
|
echo "Job failed, run ./scripts/gen_vimdoc.py and commit your doc changes"
|
||||||
echo "The doc generation produces the following changes:"
|
echo "The doc generation produces the following changes:"
|
||||||
git diff --color --exit-code
|
git diff --color --exit-code
|
||||||
|
|
||||||
- name: Automatic PR
|
|
||||||
if: ${{ steps.docs.outputs.UPDATED_DOCS != 0 && !inputs.check_only }}
|
|
||||||
run: |
|
|
||||||
git add -u
|
|
||||||
git commit -m 'docs: regenerate [skip ci]'
|
|
||||||
git push --force https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY} ${DOC_BRANCH}
|
|
||||||
gh pr create --draft --fill --base ${GITHUB_REF#refs/heads/} --head ${DOC_BRANCH} || true
|
|
||||||
|
8
.github/workflows/backport.yml
vendored
8
.github/workflows/backport.yml
vendored
@@ -8,15 +8,9 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
name: Backport Pull Request
|
name: Backport Pull Request
|
||||||
if: >
|
if: github.event.pull_request.merged
|
||||||
github.repository_owner == 'neovim' && (
|
|
||||||
github.event_name == 'pull_request_target' &&
|
|
||||||
github.event.pull_request.merged
|
|
||||||
)
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
- name: Create backport PRs
|
- name: Create backport PRs
|
||||||
uses: korthout/backport-action@v1
|
uses: korthout/backport-action@v1
|
||||||
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -67,7 +67,7 @@ jobs:
|
|||||||
run: make deps
|
run: make deps
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: make CMAKE_FLAGS="-D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX"
|
run: make CMAKE_FLAGS="-D CI_BUILD=ON -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX"
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: make install
|
run: make install
|
||||||
|
34
.github/workflows/issue-open-check.yml
vendored
Normal file
34
.github/workflows/issue-open-check.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: Issue Open Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
issue-open-check:
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: check issue title
|
||||||
|
id: check-issue
|
||||||
|
uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const title = context.payload.issue.title;
|
||||||
|
const titleSplit = title.split(/\s+/).map(e => e.toLowerCase());
|
||||||
|
const keywords = ['api', 'treesitter', 'ui', 'lsp', 'doc'];
|
||||||
|
var match = new Set();
|
||||||
|
for(const keyword of keywords) {
|
||||||
|
if(titleSplit.includes(keyword)) {
|
||||||
|
match.add(keyword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(match.size !== 0){
|
||||||
|
github.rest.issues.addLabels({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
labels: Array.from(match)
|
||||||
|
})
|
||||||
|
}
|
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
@@ -12,7 +12,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/labeler@v4
|
- uses: actions/labeler@v4
|
||||||
with:
|
with:
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
sync-labels: ""
|
sync-labels: ""
|
||||||
|
|
||||||
type-scope:
|
type-scope:
|
||||||
@@ -44,7 +43,6 @@ jobs:
|
|||||||
- name: 'Request reviewers'
|
- name: 'Request reviewers'
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v6
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.TEAM_REVIEW }}
|
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/reviews.js')
|
const script = require('./.github/scripts/reviews.js')
|
||||||
await script({github, context})
|
await script({github, context})
|
||||||
|
2
.github/workflows/lintcommit.yml
vendored
2
.github/workflows/lintcommit.yml
vendored
@@ -8,8 +8,6 @@ jobs:
|
|||||||
lint-commits:
|
lint-commits:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
6
.github/workflows/notes.md
vendored
6
.github/workflows/notes.md
vendored
@@ -9,14 +9,14 @@ ${NVIM_VERSION}
|
|||||||
#### Zip
|
#### Zip
|
||||||
|
|
||||||
1. Download **nvim-win64.zip**
|
1. Download **nvim-win64.zip**
|
||||||
2. Extract the zip.
|
2. Extract the zip
|
||||||
3. Run `nvim-qt.exe`
|
3. Run `nvim-qt.exe`
|
||||||
|
|
||||||
#### MSI
|
#### MSI
|
||||||
|
|
||||||
1. Download **nvim-win64.msi**
|
1. Download **nvim-win64.msi**
|
||||||
2. Run the MSI
|
2. Run the MSI
|
||||||
3. Search and run `nvim-qt.exe` or run `nvim.exe` on your CLI of choice.
|
3. Search and run `nvim-qt.exe` or run `nvim.exe` on your CLI of choice
|
||||||
|
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
@@ -38,8 +38,6 @@ ${NVIM_VERSION}
|
|||||||
|
|
||||||
#### Tarball
|
#### Tarball
|
||||||
|
|
||||||
*(deprecated)*
|
|
||||||
|
|
||||||
1. Download **nvim-linux64.tar.gz**
|
1. Download **nvim-linux64.tar.gz**
|
||||||
2. Extract: `tar xzvf nvim-linux64.tar.gz`
|
2. Extract: `tar xzvf nvim-linux64.tar.gz`
|
||||||
3. Run `./nvim-linux64/bin/nvim`
|
3. Run `./nvim-linux64/bin/nvim`
|
||||||
|
63
.github/workflows/release.yml
vendored
63
.github/workflows/release.yml
vendored
@@ -17,39 +17,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
linux:
|
linux:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
env:
|
||||||
|
CC: gcc-10
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.build.outputs.version }}
|
version: ${{ steps.build.outputs.version }}
|
||||||
release: ${{ steps.build.outputs.release }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Install dependencies
|
|
||||||
run: ./.github/scripts/install_deps.sh
|
|
||||||
- if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name != 'nightly')
|
|
||||||
run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV
|
|
||||||
- if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly')
|
|
||||||
run: printf 'NVIM_BUILD_TYPE=RelWithDebInfo\n' >> $GITHUB_ENV
|
|
||||||
- name: Build release
|
|
||||||
id: build
|
|
||||||
run: |
|
|
||||||
CC=gcc-10 make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCI_BUILD=OFF -DCMAKE_INSTALL_PREFIX:PATH="
|
|
||||||
printf 'version<<END\n' >> $GITHUB_OUTPUT
|
|
||||||
./build/bin/nvim --version | head -n 3 >> $GITHUB_OUTPUT
|
|
||||||
printf 'END\n' >> $GITHUB_OUTPUT
|
|
||||||
printf 'release=%s\n' "$(./build/bin/nvim --version | head -n 1)" >> $GITHUB_OUTPUT
|
|
||||||
make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-linux64" install
|
|
||||||
cd "$GITHUB_WORKSPACE/build/"
|
|
||||||
cpack -C $NVIM_BUILD_TYPE
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nvim-linux64
|
|
||||||
path: |
|
|
||||||
build/nvim-linux64.tar.gz
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
appimage:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
container:
|
container:
|
||||||
image: ubuntu:18.04
|
image: ubuntu:18.04
|
||||||
options: --privileged # Privileged mode is needed to load fuse module.
|
options: --privileged # Privileged mode is needed to load fuse module.
|
||||||
@@ -71,11 +42,19 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y build-essential cmake gettext locales ninja-build pkg-config unzip
|
apt-get install -y build-essential cmake gettext ninja-build unzip
|
||||||
- if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name != 'nightly')
|
- if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name != 'nightly')
|
||||||
run: CC=gcc-10 make appimage-latest
|
run: |
|
||||||
|
echo 'NVIM_BUILD_TYPE=Release' >> $GITHUB_ENV
|
||||||
|
echo 'APPIMAGE_TAG=latest' >> $GITHUB_ENV
|
||||||
- if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly')
|
- if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly')
|
||||||
run: CC=gcc-10 make appimage-nightly
|
run: |
|
||||||
|
echo 'NVIM_BUILD_TYPE=RelWithDebInfo' >> $GITHUB_ENV
|
||||||
|
echo 'APPIMAGE_TAG=nightly' >> $GITHUB_ENV
|
||||||
|
- name: appimage
|
||||||
|
run: ./scripts/genappimage.sh ${APPIMAGE_TAG}
|
||||||
|
- name: tar.gz
|
||||||
|
run: cpack --config build/CPackConfig.cmake -G TGZ
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: appimage
|
name: appimage
|
||||||
@@ -83,6 +62,18 @@ jobs:
|
|||||||
build/bin/nvim.appimage
|
build/bin/nvim.appimage
|
||||||
build/bin/nvim.appimage.zsync
|
build/bin/nvim.appimage.zsync
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: nvim-linux64
|
||||||
|
path: |
|
||||||
|
build/nvim-linux64.tar.gz
|
||||||
|
retention-days: 1
|
||||||
|
- name: Export version
|
||||||
|
id: build
|
||||||
|
run: |
|
||||||
|
printf 'version<<END\n' >> $GITHUB_OUTPUT
|
||||||
|
./build/bin/nvim --version | head -n 3 >> $GITHUB_OUTPUT
|
||||||
|
printf 'END\n' >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
macOS:
|
macOS:
|
||||||
runs-on: macos-11
|
runs-on: macos-11
|
||||||
@@ -126,7 +117,7 @@ jobs:
|
|||||||
cmake --build .deps
|
cmake --build .deps
|
||||||
- name: build package
|
- name: build package
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=OFF
|
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE='RelWithDebInfo'
|
||||||
cmake --build build --target package
|
cmake --build build --target package
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
@@ -137,7 +128,7 @@ jobs:
|
|||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
needs: [linux, appimage, macOS, windows]
|
needs: [linux, macOS, windows]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
GH_REPO: ${{ github.repository }}
|
GH_REPO: ${{ github.repository }}
|
||||||
|
1
.github/workflows/remove-reviewers.yml
vendored
1
.github/workflows/remove-reviewers.yml
vendored
@@ -12,7 +12,6 @@ jobs:
|
|||||||
- name: 'Remove reviewers'
|
- name: 'Remove reviewers'
|
||||||
uses: actions/github-script@v6
|
uses: actions/github-script@v6
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.TEAM_REVIEW }}
|
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/remove-reviewers.js')
|
const script = require('./.github/scripts/remove-reviewers.js')
|
||||||
await script({github, context})
|
await script({github, context})
|
||||||
|
35
.github/workflows/response.yml
vendored
Normal file
35
.github/workflows/response.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
name: no_response
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '30 1 * * *' # Run every day at 01:30
|
||||||
|
workflow_dispatch:
|
||||||
|
issue_comment:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close:
|
||||||
|
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const script = require('./.github/scripts/close_unresponsive.js')
|
||||||
|
await script({github, context})
|
||||||
|
|
||||||
|
remove_label:
|
||||||
|
if: github.event_name == 'issue_comment'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const script = require('./.github/scripts/remove_response_label.js')
|
||||||
|
await script({github, context})
|
42
.github/workflows/stale.yml
vendored
42
.github/workflows/stale.yml
vendored
@@ -1,42 +0,0 @@
|
|||||||
name: 'Close stale issues and PRs'
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '30 1 * * *' # Run every day at 01:30
|
|
||||||
workflow_dispatch:
|
|
||||||
issue_comment:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
close:
|
|
||||||
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v8
|
|
||||||
with:
|
|
||||||
days-before-close: 30
|
|
||||||
days-before-stale: -1
|
|
||||||
stale-issue-label: needs:response
|
|
||||||
stale-pr-label: needs:response
|
|
||||||
remove-stale-when-updated: false
|
|
||||||
close-issue-message: "This issue has been closed since a request for
|
|
||||||
information has not been answered for 30 days. It can be reopened
|
|
||||||
when the requested information is provided."
|
|
||||||
close-pr-message: "This PR has been closed since a request for
|
|
||||||
changes has not been answered for 30 days. It can be reopened when
|
|
||||||
the requested changes are provided."
|
|
||||||
|
|
||||||
remove-label:
|
|
||||||
if: github.event_name == 'issue_comment'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const script = require('./.github/scripts/unstale.js')
|
|
||||||
await script({github, context})
|
|
37
.github/workflows/test.yml
vendored
37
.github/workflows/test.yml
vendored
@@ -42,6 +42,13 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: ./.github/scripts/install_deps.sh lua-check
|
run: ./.github/scripts/install_deps.sh lua-check
|
||||||
|
|
||||||
|
- name: Set up Homebrew
|
||||||
|
id: homebrew
|
||||||
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
brew install stylua
|
||||||
|
|
||||||
- name: Cache uncrustify
|
- name: Cache uncrustify
|
||||||
id: cache-uncrustify
|
id: cache-uncrustify
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
@@ -76,7 +83,7 @@ jobs:
|
|||||||
|
|
||||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||||
name: configure
|
name: configure
|
||||||
run: cmake -B build -G Ninja -D CI_BUILD=OFF
|
run: cmake -B build -G Ninja
|
||||||
|
|
||||||
- if: "!cancelled()"
|
- if: "!cancelled()"
|
||||||
name: Determine if run should be aborted
|
name: Determine if run should be aborted
|
||||||
@@ -84,12 +91,8 @@ jobs:
|
|||||||
run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT
|
run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||||
name: lintstylua
|
name: stylua
|
||||||
uses: JohnnyMorganz/stylua-action@v2
|
run: cmake --build build --target lintlua-stylua
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
version: latest
|
|
||||||
args: --check runtime/
|
|
||||||
|
|
||||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||||
name: luacheck
|
name: luacheck
|
||||||
@@ -111,18 +114,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
${{ env.CACHE_UNCRUSTIFY }} -c ./src/uncrustify.cfg -q --replace --no-backup $(find ./src/nvim -name "*.[ch]")
|
${{ env.CACHE_UNCRUSTIFY }} -c ./src/uncrustify.cfg -q --replace --no-backup $(find ./src/nvim -name "*.[ch]")
|
||||||
|
|
||||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
|
||||||
name: suggester / uncrustify
|
|
||||||
uses: reviewdog/action-suggester@v1
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
tool_name: uncrustify
|
|
||||||
cleanup: false
|
|
||||||
|
|
||||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
|
||||||
name: check uncrustify
|
|
||||||
run: git diff --color --exit-code
|
|
||||||
|
|
||||||
posix:
|
posix:
|
||||||
name: ${{ matrix.runner }} ${{ matrix.flavor }} (cc=${{ matrix.cc }})
|
name: ${{ matrix.runner }} ${{ matrix.flavor }} (cc=${{ matrix.cc }})
|
||||||
strategy:
|
strategy:
|
||||||
@@ -197,7 +188,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G Ninja -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }}
|
cmake -B build -G Ninja -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.flags }} -D CI_BUILD=ON
|
||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
- if: "!cancelled()"
|
- if: "!cancelled()"
|
||||||
@@ -276,7 +267,7 @@ jobs:
|
|||||||
cmake --build .deps
|
cmake --build .deps
|
||||||
|
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: cmake -B build -G "Ninja Multi-Config" -D CMAKE_C_COMPILER=gcc
|
run: cmake -B build -G "Ninja Multi-Config" -D CMAKE_C_COMPILER=gcc -D CI_BUILD=ON
|
||||||
|
|
||||||
- name: Release
|
- name: Release
|
||||||
run: cmake --build build --config Release
|
run: cmake --build build --config Release
|
||||||
@@ -313,7 +304,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo'
|
cmake -B build -G Ninja -D CMAKE_BUILD_TYPE='RelWithDebInfo' -D CI_BUILD=ON
|
||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
- name: Install test deps
|
- name: Install test deps
|
||||||
@@ -405,5 +396,5 @@ jobs:
|
|||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G Ninja
|
cmake -B build -G Ninja -D CI_BUILD=ON
|
||||||
cmake --build build
|
cmake --build build
|
||||||
|
@@ -35,6 +35,10 @@ if(CCACHE_PRG)
|
|||||||
set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E env CCACHE_SLOPPINESS=pch_defines,time_macros ${CCACHE_PRG})
|
set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E env CCACHE_SLOPPINESS=pch_defines,time_macros ${CCACHE_PRG})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT CI_BUILD)
|
||||||
|
set(CMAKE_INSTALL_MESSAGE NEVER)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Prefer our bundled versions of dependencies.
|
# Prefer our bundled versions of dependencies.
|
||||||
if(DEFINED ENV{DEPS_BUILD_DIR})
|
if(DEFINED ENV{DEPS_BUILD_DIR})
|
||||||
set(DEPS_PREFIX "$ENV{DEPS_BUILD_DIR}/usr" CACHE PATH "Path prefix for finding dependencies")
|
set(DEPS_PREFIX "$ENV{DEPS_BUILD_DIR}/usr" CACHE PATH "Path prefix for finding dependencies")
|
||||||
@@ -106,7 +110,7 @@ set_default_buildtype()
|
|||||||
# version string, else they are combined with the result of `git describe`.
|
# version string, else they are combined with the result of `git describe`.
|
||||||
set(NVIM_VERSION_MAJOR 0)
|
set(NVIM_VERSION_MAJOR 0)
|
||||||
set(NVIM_VERSION_MINOR 9)
|
set(NVIM_VERSION_MINOR 9)
|
||||||
set(NVIM_VERSION_PATCH 0)
|
set(NVIM_VERSION_PATCH 4)
|
||||||
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
|
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
|
||||||
|
|
||||||
# API level
|
# API level
|
||||||
@@ -246,6 +250,8 @@ add_glob_target(
|
|||||||
FLAGS --color=always --check
|
FLAGS --color=always --check
|
||||||
GLOB_DIRS runtime/
|
GLOB_DIRS runtime/
|
||||||
GLOB_PAT *.lua
|
GLOB_PAT *.lua
|
||||||
|
EXCLUDE
|
||||||
|
/runtime/lua/vim/re.lua
|
||||||
TOUCH_STRATEGY SINGLE)
|
TOUCH_STRATEGY SINGLE)
|
||||||
|
|
||||||
add_custom_target(lintlua)
|
add_custom_target(lintlua)
|
||||||
|
@@ -132,15 +132,15 @@ endif()
|
|||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
set_directory_properties(PROPERTIES EP_PREFIX "${DEPS_BUILD_DIR}")
|
set_directory_properties(PROPERTIES EP_PREFIX "${DEPS_BUILD_DIR}")
|
||||||
|
|
||||||
set(LIBUV_URL https://github.com/libuv/libuv/archive/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz)
|
set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.46.0.tar.gz)
|
||||||
set(LIBUV_SHA256 c7e89137da65a1cb550ba96b892dfeeabea982bf33b9237bcf9bbcd90f2e70a1)
|
set(LIBUV_SHA256 7aa66be3413ae10605e1f5c9ae934504ffe317ef68ea16fdaa83e23905c681bd)
|
||||||
|
|
||||||
set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/c-6.0.0/msgpack-c-6.0.0.tar.gz)
|
set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/c-6.0.0/msgpack-c-6.0.0.tar.gz)
|
||||||
set(MSGPACK_SHA256 3654f5e2c652dc52e0a993e270bb57d5702b262703f03771c152bba51602aeba)
|
set(MSGPACK_SHA256 3654f5e2c652dc52e0a993e270bb57d5702b262703f03771c152bba51602aeba)
|
||||||
|
|
||||||
# https://github.com/LuaJIT/LuaJIT/tree/v2.1
|
# https://github.com/LuaJIT/LuaJIT/tree/v2.1
|
||||||
set(LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/505e2c03de35e2718eef0d2d3660712e06dadf1f.tar.gz)
|
set(LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/03c31124cc3b521ef54fe398e10fa55660a5057d.tar.gz)
|
||||||
set(LUAJIT_SHA256 67c88399b901a22e9a236f4b77e6fe39af00f6b7144ce9dd6f51141d921f1076)
|
set(LUAJIT_SHA256 61dcc7ae3f543ae3cc30e66db060e31e2a77e4be34ee65e370c953d112b4d60c)
|
||||||
|
|
||||||
set(LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz)
|
set(LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz)
|
||||||
set(LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333)
|
set(LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333)
|
||||||
@@ -151,14 +151,14 @@ set(LUAROCKS_SHA256 a0b36cd68586cd79966d0106bb2e5a4f5523327867995fd66bee4237062b
|
|||||||
set(UNIBILIUM_URL https://github.com/neovim/unibilium/archive/d72c3598e7ac5d1ebf86ee268b8b4ed95c0fa628.tar.gz)
|
set(UNIBILIUM_URL https://github.com/neovim/unibilium/archive/d72c3598e7ac5d1ebf86ee268b8b4ed95c0fa628.tar.gz)
|
||||||
set(UNIBILIUM_SHA256 9c4747c862ab5e3076dcf8fa8f0ea7a6b50f20ec5905618b9536655596797487)
|
set(UNIBILIUM_SHA256 9c4747c862ab5e3076dcf8fa8f0ea7a6b50f20ec5905618b9536655596797487)
|
||||||
|
|
||||||
set(LIBTERMKEY_URL https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/libtermkey/0.22-1/libtermkey_0.22.orig.tar.gz)
|
set(LIBTERMKEY_URL https://github.com/neovim/deps/raw/aa004f1b2b6470a92363cba8e1cc1874141dacc4/opt/libtermkey-0.22.tar.gz)
|
||||||
set(LIBTERMKEY_SHA256 6945bd3c4aaa83da83d80a045c5563da4edd7d0374c62c0d35aec09eb3014600)
|
set(LIBTERMKEY_SHA256 6945bd3c4aaa83da83d80a045c5563da4edd7d0374c62c0d35aec09eb3014600)
|
||||||
|
|
||||||
set(LIBVTERM_URL https://launchpad.net/libvterm/trunk/v0.3/+download/libvterm-0.3.1.tar.gz)
|
set(LIBVTERM_URL https://github.com/neovim/deps/raw/12c9dcf1d823ac4acbccf494c93c4774a87db11d/opt/libvterm-0.3.3.tar.gz)
|
||||||
set(LIBVTERM_SHA256 25a8ad9c15485368dfd0a8a9dca1aec8fea5c27da3fa74ec518d5d3787f0c397)
|
set(LIBVTERM_SHA256 09156f43dd2128bd347cbeebe50d9a571d32c64e0cf18d211197946aff7226e0)
|
||||||
|
|
||||||
set(LUV_URL https://github.com/luvit/luv/archive/093a977b82077591baefe1e880d37dfa2730bd54.tar.gz)
|
set(LUV_URL https://github.com/luvit/luv/archive/1.45.0-0.tar.gz)
|
||||||
set(LUV_SHA256 222b38b6425f0926218e14e7da81481fdde6f9660c1feac25a53e6fb52e886e6)
|
set(LUV_SHA256 97e89940f9eeaa8dfb34f1c19f80dd373299c42719d15228ec790f415d4e4965)
|
||||||
|
|
||||||
set(LUA_COMPAT53_URL https://github.com/keplerproject/lua-compat-5.3/archive/v0.9.tar.gz)
|
set(LUA_COMPAT53_URL https://github.com/keplerproject/lua-compat-5.3/archive/v0.9.tar.gz)
|
||||||
set(LUA_COMPAT53_SHA256 ad05540d2d96a48725bb79a1def35cf6652a4e2ec26376e2617c8ce2baa6f416)
|
set(LUA_COMPAT53_SHA256 ad05540d2d96a48725bb79a1def35cf6652a4e2ec26376e2617c8ce2baa6f416)
|
||||||
@@ -185,10 +185,10 @@ set(GETTEXT_SHA256 66415634c6e8c3fa8b71362879ec7575e27da43da562c798a8a2f223e6e47
|
|||||||
set(LIBICONV_URL https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz)
|
set(LIBICONV_URL https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz)
|
||||||
set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178)
|
set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178)
|
||||||
|
|
||||||
set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.20.2.tar.gz)
|
set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.20.5.tar.gz)
|
||||||
set(TREESITTER_C_SHA256 af66fde03feb0df4faf03750102a0d265b007e5d957057b6b293c13116a70af2 )
|
set(TREESITTER_C_SHA256 694a5408246ee45d535df9df025febecdb50bee764df64a94346b9805a5f349b )
|
||||||
set(TREESITTER_LUA_URL https://github.com/MunifTanjim/tree-sitter-lua/archive/v0.0.14.tar.gz)
|
set(TREESITTER_LUA_URL https://github.com/MunifTanjim/tree-sitter-lua/archive/v0.0.18.tar.gz)
|
||||||
set(TREESITTER_LUA_SHA256 930d0370dc15b66389869355c8e14305b9ba7aafd36edbfdb468c8023395016d)
|
set(TREESITTER_LUA_SHA256 659beef871a7fa1d9a02c23f5ebf55019aa3adce6d7f5441947781e128845256)
|
||||||
set(TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.3.0.tar.gz)
|
set(TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.3.0.tar.gz)
|
||||||
set(TREESITTER_VIM_SHA256 403acec3efb7cdb18ff3d68640fc823502a4ffcdfbb71cec3f98aa786c21cbe2)
|
set(TREESITTER_VIM_SHA256 403acec3efb7cdb18ff3d68640fc823502a4ffcdfbb71cec3f98aa786c21cbe2)
|
||||||
set(TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v2.0.0.tar.gz)
|
set(TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v2.0.0.tar.gz)
|
||||||
|
@@ -25,13 +25,6 @@ function(BuildLuajit)
|
|||||||
BUILD_COMMAND "${_luajit_BUILD_COMMAND}"
|
BUILD_COMMAND "${_luajit_BUILD_COMMAND}"
|
||||||
INSTALL_COMMAND "${_luajit_INSTALL_COMMAND}"
|
INSTALL_COMMAND "${_luajit_INSTALL_COMMAND}"
|
||||||
DEPENDS "${_luajit_DEPENDS}")
|
DEPENDS "${_luajit_DEPENDS}")
|
||||||
|
|
||||||
# Create symlink for development version manually.
|
|
||||||
if(UNIX)
|
|
||||||
add_custom_command(
|
|
||||||
TARGET ${_luajit_TARGET}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E create_symlink luajit-2.1.0-beta3 ${DEPS_BIN_DIR}/${_luajit_TARGET})
|
|
||||||
endif()
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
check_c_compiler_flag(-fno-stack-check HAS_NO_STACK_CHECK)
|
check_c_compiler_flag(-fno-stack-check HAS_NO_STACK_CHECK)
|
||||||
@@ -122,8 +115,7 @@ elseif(MINGW)
|
|||||||
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/libluajit.a ${DEPS_LIB_DIR}
|
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/libluajit.a ${DEPS_LIB_DIR}
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include/luajit-2.1
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include/luajit-2.1
|
||||||
COMMAND ${CMAKE_COMMAND} -DFROM_GLOB=${DEPS_BUILD_DIR}/src/luajit/src/*.h -DTO=${DEPS_INSTALL_DIR}/include/luajit-2.1 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyFilesGlob.cmake
|
COMMAND ${CMAKE_COMMAND} -DFROM_GLOB=${DEPS_BUILD_DIR}/src/luajit/src/*.h -DTO=${DEPS_INSTALL_DIR}/include/luajit-2.1 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyFilesGlob.cmake
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}/lua/jit
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_INSTALL_DIR}/share/luajit-2.1/jit
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_BIN_DIR}/lua/jit
|
|
||||||
)
|
)
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
|
|
||||||
@@ -139,8 +131,7 @@ elseif(MSVC)
|
|||||||
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/lua51.lib ${DEPS_LIB_DIR}/luajit.lib
|
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/lua51.lib ${DEPS_LIB_DIR}/luajit.lib
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include/luajit-2.1
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_INSTALL_DIR}/include/luajit-2.1
|
||||||
COMMAND ${CMAKE_COMMAND} -DFROM_GLOB=${DEPS_BUILD_DIR}/src/luajit/src/*.h -DTO=${DEPS_INSTALL_DIR}/include/luajit-2.1 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyFilesGlob.cmake
|
COMMAND ${CMAKE_COMMAND} -DFROM_GLOB=${DEPS_BUILD_DIR}/src/luajit/src/*.h -DTO=${DEPS_INSTALL_DIR}/include/luajit-2.1 -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CopyFilesGlob.cmake
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}/lua/jit
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_INSTALL_DIR}/share/luajit-2.1/jit
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${DEPS_BIN_DIR}/lua/jit
|
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Trying to build luajit in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}")
|
message(FATAL_ERROR "Trying to build luajit in an unsupported system ${CMAKE_SYSTEM_NAME}/${CMAKE_C_COMPILER_ID}")
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
set(CPACK_PACKAGE_NAME "Neovim")
|
set(CPACK_PACKAGE_NAME "Neovim")
|
||||||
set(CPACK_PACKAGE_VENDOR "neovim.io")
|
set(CPACK_PACKAGE_VENDOR "neovim.io")
|
||||||
set(CPACK_PACKAGE_FILE_NAME "nvim")
|
set(CPACK_PACKAGE_FILE_NAME "nvim")
|
||||||
|
set(CPACK_PACKAGE_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||||
|
|
||||||
# From the GitHub About section
|
# From the GitHub About section
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Vim-fork focused on extensibility and usability.")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Vim-fork focused on extensibility and usability.")
|
||||||
|
@@ -11,11 +11,4 @@
|
|||||||
Value='[INSTALL_ROOT]bin'
|
Value='[INSTALL_ROOT]bin'
|
||||||
/>
|
/>
|
||||||
</CPackWiXFragment>
|
</CPackWiXFragment>
|
||||||
|
|
||||||
<!-- Allow installation by non-administrative users -->
|
|
||||||
<!-- https://learn.microsoft.com/windows/win32/msi/allusers -->
|
|
||||||
<CPackWiXFragment Id="#PRODUCT">
|
|
||||||
<Property Id="ALLUSERS" Value="2" />
|
|
||||||
<Property Id="MSIINSTALLPERUSER" Value="1" />
|
|
||||||
</CPackWiXFragment>
|
|
||||||
</CPackWiXPatch>
|
</CPackWiXPatch>
|
||||||
|
@@ -25,7 +25,8 @@ function! s:selection.on_exit(jobid, data, event) abort
|
|||||||
if self.owner == a:jobid
|
if self.owner == a:jobid
|
||||||
let self.owner = 0
|
let self.owner = 0
|
||||||
endif
|
endif
|
||||||
if a:data != 0
|
" Don't print if exit code is >= 128 ( exit is 128+SIGNUM if by signal (e.g. 143 on SIGTERM))
|
||||||
|
if a:data > 0 && a:data < 128
|
||||||
echohl WarningMsg
|
echohl WarningMsg
|
||||||
echomsg 'clipboard: error invoking '.get(self.argv, 0, '?').': '.join(self.stderr)
|
echomsg 'clipboard: error invoking '.get(self.argv, 0, '?').': '.join(self.stderr)
|
||||||
echohl None
|
echohl None
|
||||||
@@ -92,9 +93,9 @@ function! provider#clipboard#Executable() abort
|
|||||||
let s:cache_enabled = 0
|
let s:cache_enabled = 0
|
||||||
return 'pbcopy'
|
return 'pbcopy'
|
||||||
elseif !empty($WAYLAND_DISPLAY) && executable('wl-copy') && executable('wl-paste')
|
elseif !empty($WAYLAND_DISPLAY) && executable('wl-copy') && executable('wl-paste')
|
||||||
let s:copy['+'] = ['wl-copy', '--foreground', '--type', 'text/plain']
|
let s:copy['+'] = ['wl-copy', '--type', 'text/plain']
|
||||||
let s:paste['+'] = ['wl-paste', '--no-newline']
|
let s:paste['+'] = ['wl-paste', '--no-newline']
|
||||||
let s:copy['*'] = ['wl-copy', '--foreground', '--primary', '--type', 'text/plain']
|
let s:copy['*'] = ['wl-copy', '--primary', '--type', 'text/plain']
|
||||||
let s:paste['*'] = ['wl-paste', '--no-newline', '--primary']
|
let s:paste['*'] = ['wl-paste', '--no-newline', '--primary']
|
||||||
return 'wl-copy'
|
return 'wl-copy'
|
||||||
elseif !empty($WAYLAND_DISPLAY) && executable('waycopy') && executable('waypaste')
|
elseif !empty($WAYLAND_DISPLAY) && executable('waycopy') && executable('waypaste')
|
||||||
|
@@ -26,7 +26,7 @@ endfunction
|
|||||||
|
|
||||||
function! s:get_python_candidates(major_version) abort
|
function! s:get_python_candidates(major_version) abort
|
||||||
return {
|
return {
|
||||||
\ 3: ['python3', 'python3.10', 'python3.9', 'python3.8', 'python3.7', 'python']
|
\ 3: ['python3', 'python3.12', 'python3.11', 'python3.10', 'python3.9', 'python3.8', 'python3.7', 'python']
|
||||||
\ }[a:major_version]
|
\ }[a:major_version]
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -61,12 +61,11 @@ endfunction
|
|||||||
|
|
||||||
" Returns array: [prog_exitcode, prog_version]
|
" Returns array: [prog_exitcode, prog_version]
|
||||||
function! s:import_module(prog, module) abort
|
function! s:import_module(prog, module) abort
|
||||||
let prog_version = system([a:prog, '-c' , printf(
|
let prog_version = system([a:prog, '-W', 'ignore', '-c', printf(
|
||||||
\ 'import sys; ' .
|
\ 'import sys, importlib.util; ' .
|
||||||
\ 'sys.path = [p for p in sys.path if p != ""]; ' .
|
\ 'sys.path = [p for p in sys.path if p != ""]; ' .
|
||||||
\ 'sys.stdout.write(str(sys.version_info[0]) + "." + str(sys.version_info[1])); ' .
|
\ 'sys.stdout.write(str(sys.version_info[0]) + "." + str(sys.version_info[1])); ' .
|
||||||
\ 'import pkgutil; ' .
|
\ 'sys.exit(2 * int(importlib.util.find_spec("%s") is None))',
|
||||||
\ 'exit(2*int(pkgutil.get_loader("%s") is None))',
|
|
||||||
\ a:module)])
|
\ a:module)])
|
||||||
return [v:shell_error, prog_version]
|
return [v:shell_error, prog_version]
|
||||||
endfunction
|
endfunction
|
||||||
|
@@ -196,6 +196,7 @@ gR Enter Virtual Replace mode: Each character you type
|
|||||||
|
|
||||||
*v_r*
|
*v_r*
|
||||||
{Visual}r{char} Replace all selected characters by {char}.
|
{Visual}r{char} Replace all selected characters by {char}.
|
||||||
|
CTRL-C will be inserted literally.
|
||||||
|
|
||||||
*v_C*
|
*v_C*
|
||||||
{Visual}["x]C Delete the highlighted lines [into register x] and
|
{Visual}["x]C Delete the highlighted lines [into register x] and
|
||||||
|
@@ -120,6 +120,8 @@ LSP FUNCTIONS
|
|||||||
{buffer = bufnr} instead.
|
{buffer = bufnr} instead.
|
||||||
- *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
|
- *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
|
||||||
{async = true} instead.
|
{async = true} instead.
|
||||||
|
- *vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
|
||||||
|
{async = false} instead.
|
||||||
- *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
|
- *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
|
||||||
or |vim.lsp.buf.format()| instead.
|
or |vim.lsp.buf.format()| instead.
|
||||||
|
|
||||||
|
@@ -295,6 +295,14 @@ DiagnosticSignHint
|
|||||||
DiagnosticSignOk
|
DiagnosticSignOk
|
||||||
Used for "Ok" signs in sign column.
|
Used for "Ok" signs in sign column.
|
||||||
|
|
||||||
|
*hl-DiagnosticDeprecated*
|
||||||
|
DiagnosticDeprecated
|
||||||
|
Used for deprecated or obsolete code.
|
||||||
|
|
||||||
|
*hl-DiagnosticUnnecessary*
|
||||||
|
DiagnosticUnnecessary
|
||||||
|
Used for unnecessary or unused code.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
SIGNS *diagnostic-signs*
|
SIGNS *diagnostic-signs*
|
||||||
|
|
||||||
|
@@ -83,14 +83,14 @@ For the most recent information about sponsoring look on the Vim web site:
|
|||||||
https://www.vim.org/sponsor/
|
https://www.vim.org/sponsor/
|
||||||
|
|
||||||
|
|
||||||
Neovim development is funded separately from Vim:
|
Nvim development is funded separately from Vim:
|
||||||
|
|
||||||
https://neovim.io/#sponsor
|
https://neovim.io/#sponsor
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Credits *credits*
|
Credits *credits*
|
||||||
|
|
||||||
Most of Vim was written by Bram Moolenaar <Bram@vim.org>.
|
Most of Vim was written by Bram Moolenaar <Bram@vim.org> |Bram-Moolenaar|
|
||||||
|
|
||||||
Parts of the documentation come from several Vi manuals, written by:
|
Parts of the documentation come from several Vi manuals, written by:
|
||||||
W.N. Joy
|
W.N. Joy
|
||||||
@@ -193,6 +193,19 @@ Elvis Another Vi clone, made by Steve Kirkendall. Very compact but isn't
|
|||||||
|
|
||||||
Vim Nvim is based on Vim. https://www.vim.org/
|
Vim Nvim is based on Vim. https://www.vim.org/
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
Bram Moolenaar *Bram* *Moolenaar* *Bram-Moolenaar* *brammool*
|
||||||
|
|
||||||
|
Nvim is a fork of the Vim ("Vi IMproved") text editor, which was originally
|
||||||
|
developed by Bram Moolenaar. Searching his name within the source code of
|
||||||
|
Nvim will reveal just how much of his work still remains in Nvim.
|
||||||
|
On August 3, 2023, he passed away at the age of 62. If Vim or Nvim have been
|
||||||
|
of use to you in your life, please read |Uganda| and consider honoring his
|
||||||
|
memory however you may see fit.
|
||||||
|
|
||||||
|
Obituary Articles: https://github.com/vim/vim/discussions/12742
|
||||||
|
Say Farewell: https://github.com/vim/vim/discussions/12737
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Notation *notation*
|
Notation *notation*
|
||||||
|
|
||||||
@@ -372,6 +385,7 @@ notation meaning equivalent decimal value(s) ~
|
|||||||
<C-…> control-key *control* *ctrl* *<C-*
|
<C-…> control-key *control* *ctrl* *<C-*
|
||||||
<M-…> alt-key or meta-key *META* *ALT* *<M-*
|
<M-…> alt-key or meta-key *META* *ALT* *<M-*
|
||||||
<A-…> same as <M-…> *<A-*
|
<A-…> same as <M-…> *<A-*
|
||||||
|
<T-…> meta-key when it's not alt *<T-*
|
||||||
<D-…> command-key or "super" key *<D-*
|
<D-…> command-key or "super" key *<D-*
|
||||||
----------------------------------------------------------------------- ~
|
----------------------------------------------------------------------- ~
|
||||||
|
|
||||||
@@ -385,7 +399,7 @@ Note:
|
|||||||
combinations actually work depends on the UI or host terminal.
|
combinations actually work depends on the UI or host terminal.
|
||||||
- When a key is pressed using a meta or alt modifier and no mapping exists for
|
- When a key is pressed using a meta or alt modifier and no mapping exists for
|
||||||
that keypress, Nvim may behave as though <Esc> was pressed before the key.
|
that keypress, Nvim may behave as though <Esc> was pressed before the key.
|
||||||
- It is possible to notate combined modifiers (e.g. <C-A-T> for CTRL-ALT-T),
|
- It is possible to notate combined modifiers (e.g. <M-C-T> for CTRL-ALT-T),
|
||||||
but your terminal must encode the input for that to work. |tui-input|
|
but your terminal must encode the input for that to work. |tui-input|
|
||||||
|
|
||||||
*<>*
|
*<>*
|
||||||
|
@@ -974,8 +974,7 @@ start_client({config}) *vim.lsp.start_client()*
|
|||||||
passed to the language server on initialization. Hint: use
|
passed to the language server on initialization. Hint: use
|
||||||
make_client_capabilities() and modify its result.
|
make_client_capabilities() and modify its result.
|
||||||
• Note: To send an empty dictionary use
|
• Note: To send an empty dictionary use
|
||||||
`{[vim.type_idx]=vim.types.dictionary}`, else it will be
|
|vim.empty_dict()|, else it will be encoded as an array.
|
||||||
encoded as an array.
|
|
||||||
|
|
||||||
• handlers: Map of language server method names to
|
• handlers: Map of language server method names to
|
||||||
|lsp-handler|
|
|lsp-handler|
|
||||||
@@ -2130,27 +2129,6 @@ start({cmd}, {cmd_args}, {dispatchers}, {extra_spawn_params})
|
|||||||
• `terminate()` terminates the RPC client.
|
• `terminate()` terminates the RPC client.
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Lua module: vim.lsp.sync *lsp-sync*
|
|
||||||
|
|
||||||
*vim.lsp.sync.compute_diff()*
|
|
||||||
compute_diff({___MissingCloseParenHere___})
|
|
||||||
Returns the range table for the difference between prev and curr lines
|
|
||||||
|
|
||||||
Parameters: ~
|
|
||||||
• {prev_lines} (table) list of lines
|
|
||||||
• {curr_lines} (table) list of lines
|
|
||||||
• {firstline} (integer) line to begin search for first difference
|
|
||||||
• {lastline} (integer) line to begin search in old_lines for
|
|
||||||
last difference
|
|
||||||
• {new_lastline} (integer) line to begin search in new_lines for
|
|
||||||
last difference
|
|
||||||
• {offset_encoding} (string) encoding requested by language server
|
|
||||||
|
|
||||||
Return: ~
|
|
||||||
(table) TextDocumentContentChangeEvent see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentContentChangeEvent
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Lua module: vim.lsp.protocol *lsp-protocol*
|
Lua module: vim.lsp.protocol *lsp-protocol*
|
||||||
|
|
||||||
|
@@ -318,6 +318,6 @@ release.
|
|||||||
|
|
||||||
• |nvim_exec()| is now deprecated in favor of |nvim_exec2()|.
|
• |nvim_exec()| is now deprecated in favor of |nvim_exec2()|.
|
||||||
|
|
||||||
• Renamed |vim.pretty_print| to |vim.print|.
|
• Renamed |vim.pretty_print()| to |vim.print()|.
|
||||||
|
|
||||||
vim:tw=78:ts=8:sw=2:et:ft=help:norl:
|
vim:tw=78:ts=8:sw=2:et:ft=help:norl:
|
||||||
|
@@ -2768,8 +2768,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
'fsync' 'fs' boolean (default off)
|
'fsync' 'fs' boolean (default off)
|
||||||
global
|
global
|
||||||
When on, the OS function fsync() will be called after saving a file
|
When on, the OS function fsync() will be called after saving a file
|
||||||
(|:write|, |writefile()|, …), |swap-file| and |shada-file|. This
|
(|:write|, |writefile()|, …), |swap-file|, |undo-persistence| and |shada-file|.
|
||||||
flushes the file to disk, ensuring that it is safely written.
|
This flushes the file to disk, ensuring that it is safely written.
|
||||||
Slow on some systems: writing buffers, quitting Nvim, and other
|
Slow on some systems: writing buffers, quitting Nvim, and other
|
||||||
operations may sometimes take a few seconds.
|
operations may sometimes take a few seconds.
|
||||||
|
|
||||||
@@ -5706,6 +5706,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
Name of the word list file where words are added for the |zg| and |zw|
|
Name of the word list file where words are added for the |zg| and |zw|
|
||||||
commands. It must end in ".{encoding}.add". You need to include the
|
commands. It must end in ".{encoding}.add". You need to include the
|
||||||
path, otherwise the file is placed in the current directory.
|
path, otherwise the file is placed in the current directory.
|
||||||
|
The path may include characters from 'isfname', space, comma and '@'.
|
||||||
*E765*
|
*E765*
|
||||||
It may also be a comma-separated list of names. A count before the
|
It may also be a comma-separated list of names. A count before the
|
||||||
|zg| and |zw| commands can be used to access each. This allows using
|
|zg| and |zw| commands can be used to access each. This allows using
|
||||||
|
@@ -1120,21 +1120,24 @@ LanguageTree:parse({self}) *LanguageTree:parse()*
|
|||||||
Return: ~
|
Return: ~
|
||||||
TSTree[]
|
TSTree[]
|
||||||
|
|
||||||
LanguageTree:register_cbs({self}, {cbs}) *LanguageTree:register_cbs()*
|
*LanguageTree:register_cbs()*
|
||||||
|
LanguageTree:register_cbs({self}, {cbs}, {recursive})
|
||||||
Registers callbacks for the |LanguageTree|.
|
Registers callbacks for the |LanguageTree|.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {cbs} (table) An |nvim_buf_attach()|-like table argument with the
|
• {cbs} (table) An |nvim_buf_attach()|-like table argument with
|
||||||
following handlers:
|
the following handlers:
|
||||||
• `on_bytes` : see |nvim_buf_attach()|, but this will be called after the parsers callback.
|
• `on_bytes` : see |nvim_buf_attach()|, but this will be called after the parsers callback.
|
||||||
• `on_changedtree` : a callback that will be called every time
|
• `on_changedtree` : a callback that will be called
|
||||||
the tree has syntactical changes. It will only be passed one
|
every time the tree has syntactical changes. It will
|
||||||
argument, which is a table of the ranges (as node ranges)
|
only be passed one argument, which is a table of the
|
||||||
that changed.
|
ranges (as node ranges) that changed.
|
||||||
• `on_child_added` : emitted when a child is added to the
|
• `on_child_added` : emitted when a child is added to
|
||||||
tree.
|
|
||||||
• `on_child_removed` : emitted when a child is removed from
|
|
||||||
the tree.
|
the tree.
|
||||||
|
• `on_child_removed` : emitted when a child is removed
|
||||||
|
from the tree.
|
||||||
|
• {recursive?} boolean Apply callbacks recursively for all children.
|
||||||
|
Any new children will also inherit the callbacks.
|
||||||
• {self}
|
• {self}
|
||||||
|
|
||||||
LanguageTree:source({self}) *LanguageTree:source()*
|
LanguageTree:source({self}) *LanguageTree:source()*
|
||||||
|
@@ -78,14 +78,14 @@ Example of a typical "redraw" batch in a single RPC notification: >
|
|||||||
[
|
[
|
||||||
['grid_resize', [2, 77, 36]],
|
['grid_resize', [2, 77, 36]],
|
||||||
['grid_line',
|
['grid_line',
|
||||||
[2, 0, 0, [[' ' , 0, 77]]],
|
[2, 0, 0, [[' ' , 0, 77]], false],
|
||||||
[2, 1, 0, [['~', 7], [' ', 7, 76]]],
|
[2, 1, 0, [['~', 7], [' ', 7, 76]], false],
|
||||||
[2, 9, 0, [['~', 7], [' ', 7, 76]]],
|
[2, 9, 0, [['~', 7], [' ', 7, 76]], false],
|
||||||
...
|
...
|
||||||
[2, 35, 0, [['~', 7], [' ', 7, 76]]],
|
[2, 35, 0, [['~', 7], [' ', 7, 76]], false],
|
||||||
[1, 36, 0, [['[', 9], ['N'], ['o'], [' '], ['N'], ['a'], ['m'], ['e'], [']']]],
|
[1, 36, 0, [['[', 9], ['N'], ['o'], [' '], ['N'], ['a'], ['m'], ['e'], [']']], false],
|
||||||
[1, 36, 9, [[' ', 9, 50]]],
|
[1, 36, 9, [[' ', 9, 50]], false],
|
||||||
[1, 36, 59, [['0', 9], [','], ['0'], ['-' ], ['1'], [' ', 9, 10], ['A'], ['l', 9, 2]]]
|
[1, 36, 59, [['0', 9], [','], ['0'], ['-' ], ['1'], [' ', 9, 10], ['A'], ['l', 9, 2]], false]
|
||||||
],
|
],
|
||||||
['msg_showmode', [[]]],
|
['msg_showmode', [[]]],
|
||||||
['win_pos', [2, 1000, 0, 0, 77, 36]],
|
['win_pos', [2, 1000, 0, 0, 77, 36]],
|
||||||
@@ -199,7 +199,7 @@ the editor.
|
|||||||
The following keys are deprecated:
|
The following keys are deprecated:
|
||||||
|
|
||||||
`hl_id`: Use `attr_id` instead.
|
`hl_id`: Use `attr_id` instead.
|
||||||
`hl_lm`: Use `attr_id_lm` instead.
|
`id_lm`: Use `attr_id_lm` instead.
|
||||||
|
|
||||||
["option_set", name, value] ~
|
["option_set", name, value] ~
|
||||||
UI-related option changed, where `name` is one of:
|
UI-related option changed, where `name` is one of:
|
||||||
@@ -336,7 +336,7 @@ numerical highlight ids to the actual attributes.
|
|||||||
|
|
||||||
Highlights are always transmitted both for both the RGB format and as
|
Highlights are always transmitted both for both the RGB format and as
|
||||||
terminal 256-color codes, as the `rgb_attr` and `cterm_attr` parameters
|
terminal 256-color codes, as the `rgb_attr` and `cterm_attr` parameters
|
||||||
respectively. The |ui-rgb| option has no effect effect anymore.
|
respectively. The |ui-rgb| option has no effect anymore.
|
||||||
Most external UIs will only need to store and use the `rgb_attr`
|
Most external UIs will only need to store and use the `rgb_attr`
|
||||||
attributes.
|
attributes.
|
||||||
|
|
||||||
@@ -352,7 +352,7 @@ numerical highlight ids to the actual attributes.
|
|||||||
|ui-hlstate| extension explained below.
|
|ui-hlstate| extension explained below.
|
||||||
|
|
||||||
["hl_group_set", name, hl_id] ~
|
["hl_group_set", name, hl_id] ~
|
||||||
The bulitin highlight group `name` was set to use the attributes `hl_id`
|
The built-in highlight group `name` was set to use the attributes `hl_id`
|
||||||
defined by a previous `hl_attr_define` call. This event is not needed
|
defined by a previous `hl_attr_define` call. This event is not needed
|
||||||
to render the grids which use attribute ids directly, but is useful
|
to render the grids which use attribute ids directly, but is useful
|
||||||
for a UI who want to render its own elements with consistent
|
for a UI who want to render its own elements with consistent
|
||||||
@@ -360,7 +360,7 @@ numerical highlight ids to the actual attributes.
|
|||||||
use the |hl-Pmenu| family of builtin highlights.
|
use the |hl-Pmenu| family of builtin highlights.
|
||||||
|
|
||||||
*ui-event-grid_line*
|
*ui-event-grid_line*
|
||||||
["grid_line", grid, row, col_start, cells] ~
|
["grid_line", grid, row, col_start, cells, wrap] ~
|
||||||
Redraw a continuous part of a `row` on a `grid`, starting at the column
|
Redraw a continuous part of a `row` on a `grid`, starting at the column
|
||||||
`col_start`. `cells` is an array of arrays each with 1 to 3 items:
|
`col_start`. `cells` is an array of arrays each with 1 to 3 items:
|
||||||
`[text(, hl_id, repeat)]` . `text` is the UTF-8 text that should be put in
|
`[text(, hl_id, repeat)]` . `text` is the UTF-8 text that should be put in
|
||||||
@@ -379,6 +379,12 @@ numerical highlight ids to the actual attributes.
|
|||||||
enough to cover the remaining line, will be sent when the rest of the
|
enough to cover the remaining line, will be sent when the rest of the
|
||||||
line should be cleared.
|
line should be cleared.
|
||||||
|
|
||||||
|
`wrap` is a boolean indicating that this line wraps to the next row.
|
||||||
|
When redrawing a line which wraps to the next row, Nvim will emit a
|
||||||
|
`grid_line` event covering the last column of the line with `wrap` set
|
||||||
|
to true, followed immediately by a `grid_line` event starting at the
|
||||||
|
first column of the next row.
|
||||||
|
|
||||||
["grid_clear", grid] ~
|
["grid_clear", grid] ~
|
||||||
Clear a `grid`.
|
Clear a `grid`.
|
||||||
|
|
||||||
@@ -634,7 +640,15 @@ tabs.
|
|||||||
the top line of a window moved since `win_viewport` was last emitted.
|
the top line of a window moved since `win_viewport` was last emitted.
|
||||||
It is intended to be used to implement smooth scrolling. For this
|
It is intended to be used to implement smooth scrolling. For this
|
||||||
purpose it only counts "virtual" or "displayed" lines, so folds
|
purpose it only counts "virtual" or "displayed" lines, so folds
|
||||||
only count as one line.
|
only count as one line. When scrolling more than a full screen it is
|
||||||
|
an approximate value.
|
||||||
|
|
||||||
|
All updates, such as `grid_line`, in a batch affects the new viewport,
|
||||||
|
despite the fact that `win_viewport` is received after the updates.
|
||||||
|
Applications implementing, for example, smooth scrolling should take
|
||||||
|
this into account and keep the grid separated from what's displayed on
|
||||||
|
the screen and copy it to the viewport destination once `win_viewport`
|
||||||
|
is received.
|
||||||
|
|
||||||
["win_extmark", grid, win, ns_id, mark_id, row, col] ~
|
["win_extmark", grid, win, ns_id, mark_id, row, col] ~
|
||||||
Updates the position of an extmark which is currently visible in a
|
Updates the position of an extmark which is currently visible in a
|
||||||
@@ -710,7 +724,7 @@ For command-line 'wildmenu' UI events, activate |ui-popupmenu|.
|
|||||||
to distinguish different command lines active at the same time. The
|
to distinguish different command lines active at the same time. The
|
||||||
first invoked command line has level 1, the next recursively-invoked
|
first invoked command line has level 1, the next recursively-invoked
|
||||||
prompt has level 2. A command line invoked from the |cmdline-window|
|
prompt has level 2. A command line invoked from the |cmdline-window|
|
||||||
has a higher level than than the edited command line.
|
has a higher level than the edited command line.
|
||||||
|
|
||||||
["cmdline_pos", pos, level] ~
|
["cmdline_pos", pos, level] ~
|
||||||
Change the cursor position in the cmdline.
|
Change the cursor position in the cmdline.
|
||||||
|
@@ -169,6 +169,7 @@ If you want to highlight exactly the same area as the last time, you can use
|
|||||||
CTRL-C In Visual mode: Stop Visual mode. When insert mode is
|
CTRL-C In Visual mode: Stop Visual mode. When insert mode is
|
||||||
pending (the mode message shows
|
pending (the mode message shows
|
||||||
"-- (insert) VISUAL --"), it is also stopped.
|
"-- (insert) VISUAL --"), it is also stopped.
|
||||||
|
On MS-Windows, you may need to press CTRL-Break.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
3. Changing the Visual area *visual-change*
|
3. Changing the Visual area *visual-change*
|
||||||
|
@@ -8,6 +8,9 @@ vim.api.nvim_create_augroup('filetypedetect', { clear = false })
|
|||||||
vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
|
vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
|
||||||
group = 'filetypedetect',
|
group = 'filetypedetect',
|
||||||
callback = function(args)
|
callback = function(args)
|
||||||
|
if not vim.api.nvim_buf_is_valid(args.buf) then
|
||||||
|
return
|
||||||
|
end
|
||||||
local ft, on_detect = vim.filetype.match({ filename = args.match, buf = args.buf })
|
local ft, on_detect = vim.filetype.match({ filename = args.match, buf = args.buf })
|
||||||
if not ft then
|
if not ft then
|
||||||
-- Generic configuration file used as fallback
|
-- Generic configuration file used as fallback
|
||||||
|
@@ -28,9 +28,12 @@ augroup filetypeplugin
|
|||||||
" When there is a dot it is used to separate filetype names. Thus for
|
" When there is a dot it is used to separate filetype names. Thus for
|
||||||
" "aaa.bbb" load "aaa" and then "bbb".
|
" "aaa.bbb" load "aaa" and then "bbb".
|
||||||
for name in split(s, '\.')
|
for name in split(s, '\.')
|
||||||
exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim'
|
" Load Lua ftplugins after Vim ftplugins _per directory_
|
||||||
" Load lua ftplugins
|
" TODO(clason): use nvim__get_runtime when supports globs and modeline
|
||||||
exe printf('runtime! ftplugin/%s.lua ftplugin/%s_*.lua ftplugin/%s/*.lua', name, name, name)
|
exe printf('runtime! ftplugin/%s.vim ftplugin/%s.lua
|
||||||
|
\ ftplugin/%s_*.vim ftplugin/%s_*.lua
|
||||||
|
\ ftplugin/%s/*.vim ftplugin/%s/*.lua',
|
||||||
|
\ name, name, name, name, name, name)
|
||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
|
1
runtime/ftplugin/cs.lua
Normal file
1
runtime/ftplugin/cs.lua
Normal file
@@ -0,0 +1 @@
|
|||||||
|
vim.bo.commentstring = '/*%s*/'
|
1
runtime/ftplugin/d.lua
Normal file
1
runtime/ftplugin/d.lua
Normal file
@@ -0,0 +1 @@
|
|||||||
|
vim.bo.commentstring = '/*%s*/'
|
@@ -1,5 +1,6 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
--- @type table<string,fun(bufnr: integer, val: string, opts?: table)>
|
||||||
M.properties = {}
|
M.properties = {}
|
||||||
|
|
||||||
--- Modified version of the builtin assert that does not include error position information
|
--- Modified version of the builtin assert that does not include error position information
|
||||||
@@ -19,7 +20,7 @@ end
|
|||||||
---
|
---
|
||||||
---@private
|
---@private
|
||||||
local function warn(msg, ...)
|
local function warn(msg, ...)
|
||||||
vim.notify(string.format(msg, ...), vim.log.levels.WARN, {
|
vim.notify_once(string.format(msg, ...), vim.log.levels.WARN, {
|
||||||
title = 'editorconfig',
|
title = 'editorconfig',
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@@ -111,7 +112,20 @@ end
|
|||||||
function M.properties.insert_final_newline(bufnr, val)
|
function M.properties.insert_final_newline(bufnr, val)
|
||||||
assert(val == 'true' or val == 'false', 'insert_final_newline must be either "true" or "false"')
|
assert(val == 'true' or val == 'false', 'insert_final_newline must be either "true" or "false"')
|
||||||
vim.bo[bufnr].fixendofline = val == 'true'
|
vim.bo[bufnr].fixendofline = val == 'true'
|
||||||
vim.bo[bufnr].endofline = val == 'true'
|
|
||||||
|
-- 'endofline' can be read to detect if the file contains a final newline,
|
||||||
|
-- so only change 'endofline' right before writing the file
|
||||||
|
local endofline = val == 'true'
|
||||||
|
if vim.bo[bufnr].endofline ~= endofline then
|
||||||
|
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||||
|
group = 'editorconfig',
|
||||||
|
buffer = bufnr,
|
||||||
|
once = true,
|
||||||
|
callback = function()
|
||||||
|
vim.bo[bufnr].endofline = endofline
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Modified version of |glob2regpat()| that does not match path separators on *.
|
--- Modified version of |glob2regpat()| that does not match path separators on *.
|
||||||
@@ -168,12 +182,12 @@ end
|
|||||||
---
|
---
|
||||||
---@param filepath string File path of the file to apply EditorConfig settings to
|
---@param filepath string File path of the file to apply EditorConfig settings to
|
||||||
---@param dir string Current directory
|
---@param dir string Current directory
|
||||||
---@return table Table of options to apply to the given file
|
---@return table<string,string|boolean> Table of options to apply to the given file
|
||||||
---
|
---
|
||||||
---@private
|
---@private
|
||||||
local function parse(filepath, dir)
|
local function parse(filepath, dir)
|
||||||
local pat = nil
|
local pat --- @type vim.regex?
|
||||||
local opts = {}
|
local opts = {} --- @type table<string,string|boolean>
|
||||||
local f = io.open(dir .. '/.editorconfig')
|
local f = io.open(dir .. '/.editorconfig')
|
||||||
if f then
|
if f then
|
||||||
for line in f:lines() do
|
for line in f:lines() do
|
||||||
@@ -189,6 +203,7 @@ local function parse(filepath, dir)
|
|||||||
end
|
end
|
||||||
elseif key ~= nil and val ~= nil then
|
elseif key ~= nil and val ~= nil then
|
||||||
if key == 'root' then
|
if key == 'root' then
|
||||||
|
assert(val == 'true' or val == 'false', 'root must be either "true" or "false"')
|
||||||
opts.root = val == 'true'
|
opts.root = val == 'true'
|
||||||
elseif pat and pat:match_str(filepath) then
|
elseif pat and pat:match_str(filepath) then
|
||||||
opts[key] = val
|
opts[key] = val
|
||||||
@@ -207,12 +222,16 @@ end
|
|||||||
---@private
|
---@private
|
||||||
function M.config(bufnr)
|
function M.config(bufnr)
|
||||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||||
|
if not vim.api.nvim_buf_is_valid(bufnr) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local path = vim.fs.normalize(vim.api.nvim_buf_get_name(bufnr))
|
local path = vim.fs.normalize(vim.api.nvim_buf_get_name(bufnr))
|
||||||
if vim.bo[bufnr].buftype ~= '' or not vim.bo[bufnr].modifiable or path == '' then
|
if vim.bo[bufnr].buftype ~= '' or not vim.bo[bufnr].modifiable or path == '' then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local opts = {}
|
local opts = {} --- @type table<string,string|boolean>
|
||||||
for parent in vim.fs.parents(path) do
|
for parent in vim.fs.parents(path) do
|
||||||
for k, v in pairs(parse(path, parent)) do
|
for k, v in pairs(parse(path, parent)) do
|
||||||
if opts[k] == nil then
|
if opts[k] == nil then
|
||||||
@@ -225,7 +244,7 @@ function M.config(bufnr)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local applied = {}
|
local applied = {} --- @type table<string,string|boolean>
|
||||||
for opt, val in pairs(opts) do
|
for opt, val in pairs(opts) do
|
||||||
if val ~= 'unset' then
|
if val ~= 'unset' then
|
||||||
local func = M.properties[opt]
|
local func = M.properties[opt]
|
||||||
|
@@ -64,6 +64,7 @@ local function system(cmd_, silent, env)
|
|||||||
local cmd_str = table.concat(cmd, ' ')
|
local cmd_str = table.concat(cmd, ' ')
|
||||||
man_error(string.format('command error: %s', cmd_str))
|
man_error(string.format('command error: %s', cmd_str))
|
||||||
end
|
end
|
||||||
|
return ''
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.wait(30000, function()
|
vim.wait(30000, function()
|
||||||
@@ -582,7 +583,7 @@ local function get_paths(sect, name)
|
|||||||
|
|
||||||
local mandirs = table.concat(vim.split(mandirs_raw, '[:\n]', { trimempty = true }), ',')
|
local mandirs = table.concat(vim.split(mandirs_raw, '[:\n]', { trimempty = true }), ',')
|
||||||
---@type string[]
|
---@type string[]
|
||||||
local paths = fn.globpath(mandirs, 'man?/' .. name .. '*.' .. sect .. '*', false, true)
|
local paths = fn.globpath(mandirs, 'man[^\\/]*/' .. name .. '*.' .. sect .. '*', false, true)
|
||||||
|
|
||||||
-- Prioritize the result from find_path as it obeys b:man_default_sects.
|
-- Prioritize the result from find_path as it obeys b:man_default_sects.
|
||||||
local first = M.find_path(sect, name)
|
local first = M.find_path(sect, name)
|
||||||
@@ -738,7 +739,12 @@ function M.open_page(count, smods, args)
|
|||||||
else
|
else
|
||||||
-- Combine the name and sect into a manpage reference so that all
|
-- Combine the name and sect into a manpage reference so that all
|
||||||
-- verification/extraction can be kept in a single function.
|
-- verification/extraction can be kept in a single function.
|
||||||
if tonumber(args[1]) then
|
if args[1]:match('^%d$') or args[1]:match('^%d%a') or args[1]:match('^%a$') then
|
||||||
|
-- NB: Valid sections are not only digits, but also:
|
||||||
|
-- - <digit><word> (see POSIX mans),
|
||||||
|
-- - and even <letter> and <word> (see, for example, by tcl/tk)
|
||||||
|
-- NB2: don't optimize to :match("^%d"), as it will match manpages like
|
||||||
|
-- 441toppm and others whose name starts with digit
|
||||||
local sect = args[1]
|
local sect = args[1]
|
||||||
table.remove(args, 1)
|
table.remove(args, 1)
|
||||||
local name = table.concat(args, ' ')
|
local name = table.concat(args, ' ')
|
||||||
|
@@ -839,7 +839,7 @@ function vim._cs_remote(rcid, server_addr, connect_error, args)
|
|||||||
or subcmd == 'tab-wait'
|
or subcmd == 'tab-wait'
|
||||||
or subcmd == 'tab-wait-silent'
|
or subcmd == 'tab-wait-silent'
|
||||||
then
|
then
|
||||||
return { errmsg = 'E5600: Wait commands not yet implemented in nvim' }
|
return { errmsg = 'E5600: Wait commands not yet implemented in Nvim' }
|
||||||
elseif subcmd == 'tab-silent' then
|
elseif subcmd == 'tab-silent' then
|
||||||
f_tab = true
|
f_tab = true
|
||||||
f_silent = true
|
f_silent = true
|
||||||
@@ -847,14 +847,14 @@ function vim._cs_remote(rcid, server_addr, connect_error, args)
|
|||||||
if rcid == 0 then
|
if rcid == 0 then
|
||||||
return { errmsg = connection_failure_errmsg('Send failed.') }
|
return { errmsg = connection_failure_errmsg('Send failed.') }
|
||||||
end
|
end
|
||||||
vim.fn.rpcrequest(rcid, 'nvim_input', args[2])
|
vim.rpcrequest(rcid, 'nvim_input', args[2])
|
||||||
return { should_exit = true, tabbed = false }
|
return { should_exit = true, tabbed = false }
|
||||||
elseif subcmd == 'expr' then
|
elseif subcmd == 'expr' then
|
||||||
if rcid == 0 then
|
if rcid == 0 then
|
||||||
return { errmsg = connection_failure_errmsg('Send expression failed.') }
|
return { errmsg = connection_failure_errmsg('Send expression failed.') }
|
||||||
end
|
end
|
||||||
print(vim.fn.rpcrequest(rcid, 'nvim_eval', args[2]))
|
local res = tostring(vim.rpcrequest(rcid, 'nvim_eval', args[2]))
|
||||||
return { should_exit = true, tabbed = false }
|
return { result = res, should_exit = true, tabbed = false }
|
||||||
elseif subcmd ~= '' then
|
elseif subcmd ~= '' then
|
||||||
return { errmsg = 'Unknown option argument: ' .. args[1] }
|
return { errmsg = 'Unknown option argument: ' .. args[1] }
|
||||||
end
|
end
|
||||||
@@ -968,6 +968,6 @@ function vim._init_defaults()
|
|||||||
vim._init_default_autocmds()
|
vim._init_default_autocmds()
|
||||||
end
|
end
|
||||||
|
|
||||||
require('vim._meta')
|
require('vim._options')
|
||||||
|
|
||||||
return vim
|
return vim
|
||||||
|
@@ -70,15 +70,18 @@ function vim.inspect_pos(bufnr, row, col, filter)
|
|||||||
if filter.treesitter then
|
if filter.treesitter then
|
||||||
for _, capture in pairs(vim.treesitter.get_captures_at_pos(bufnr, row, col)) do
|
for _, capture in pairs(vim.treesitter.get_captures_at_pos(bufnr, row, col)) do
|
||||||
capture.hl_group = '@' .. capture.capture .. '.' .. capture.lang
|
capture.hl_group = '@' .. capture.capture .. '.' .. capture.lang
|
||||||
table.insert(results.treesitter, resolve_hl(capture))
|
results.treesitter[#results.treesitter + 1] = resolve_hl(capture)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- syntax
|
-- syntax
|
||||||
if filter.syntax then
|
if filter.syntax and vim.api.nvim_buf_is_valid(bufnr) then
|
||||||
|
vim.api.nvim_buf_call(bufnr, function()
|
||||||
for _, i1 in ipairs(vim.fn.synstack(row + 1, col + 1)) do
|
for _, i1 in ipairs(vim.fn.synstack(row + 1, col + 1)) do
|
||||||
table.insert(results.syntax, resolve_hl({ hl_group = vim.fn.synIDattr(i1, 'name') }))
|
results.syntax[#results.syntax + 1] =
|
||||||
|
resolve_hl({ hl_group = vim.fn.synIDattr(i1, 'name') })
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- namespace id -> name map
|
-- namespace id -> name map
|
||||||
|
@@ -526,7 +526,10 @@ local function create_option_accessor(scope)
|
|||||||
|
|
||||||
return setmetatable({}, {
|
return setmetatable({}, {
|
||||||
__index = function(_, k)
|
__index = function(_, k)
|
||||||
return make_option(k, api.nvim_get_option_value(k, {}))
|
-- vim.opt_global must get global value only
|
||||||
|
-- vim.opt_local may fall back to global value like vim.opt
|
||||||
|
local opts = { scope = scope == 'global' and 'global' or nil }
|
||||||
|
return make_option(k, api.nvim_get_option_value(k, opts))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
@@ -88,6 +88,9 @@ local default_poll_interval_ms = 2000
|
|||||||
--- be invoked recursively)
|
--- be invoked recursively)
|
||||||
--- - children (table|nil)
|
--- - children (table|nil)
|
||||||
--- A mapping of directory entry name to its recursive watches
|
--- A mapping of directory entry name to its recursive watches
|
||||||
|
-- - started (boolean|nil)
|
||||||
|
-- Whether or not the watcher has first been initialized. Used
|
||||||
|
-- to prevent a flood of Created events on startup.
|
||||||
local function poll_internal(path, opts, callback, watches)
|
local function poll_internal(path, opts, callback, watches)
|
||||||
path = vim.fs.normalize(path)
|
path = vim.fs.normalize(path)
|
||||||
local interval = opts and opts.interval or default_poll_interval_ms
|
local interval = opts and opts.interval or default_poll_interval_ms
|
||||||
@@ -112,8 +115,10 @@ local function poll_internal(path, opts, callback, watches)
|
|||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
assert(not start_err, start_err)
|
assert(not start_err, start_err)
|
||||||
|
if watches.started then
|
||||||
callback(path, M.FileChangeType.Created)
|
callback(path, M.FileChangeType.Created)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
watches.cancel = function()
|
watches.cancel = function()
|
||||||
if watches.children then
|
if watches.children then
|
||||||
@@ -132,6 +137,7 @@ local function poll_internal(path, opts, callback, watches)
|
|||||||
if not watches.children[name] then
|
if not watches.children[name] then
|
||||||
watches.children[name] = {
|
watches.children[name] = {
|
||||||
is_dir = ftype == 'directory',
|
is_dir = ftype == 'directory',
|
||||||
|
started = watches.started,
|
||||||
}
|
}
|
||||||
poll_internal(filepath_join(path, name), opts, callback, watches.children[name])
|
poll_internal(filepath_join(path, name), opts, callback, watches.children[name])
|
||||||
end
|
end
|
||||||
@@ -150,6 +156,8 @@ local function poll_internal(path, opts, callback, watches)
|
|||||||
watches.children = newchildren
|
watches.children = newchildren
|
||||||
end
|
end
|
||||||
|
|
||||||
|
watches.started = true
|
||||||
|
|
||||||
return watches.cancel
|
return watches.cancel
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -1550,8 +1550,15 @@ local patterns_text = {
|
|||||||
['^SNNS pattern definition file'] = 'snnspat',
|
['^SNNS pattern definition file'] = 'snnspat',
|
||||||
['^SNNS result file'] = 'snnsres',
|
['^SNNS result file'] = 'snnsres',
|
||||||
['^%%.-[Vv]irata'] = { 'virata', { start_lnum = 1, end_lnum = 5 } },
|
['^%%.-[Vv]irata'] = { 'virata', { start_lnum = 1, end_lnum = 5 } },
|
||||||
['[0-9:%.]* *execve%('] = 'strace',
|
function(lines)
|
||||||
['^__libc_start_main'] = 'strace',
|
if
|
||||||
|
-- inaccurate fast match first, then use accurate slow match
|
||||||
|
(lines[1]:find('execve%(') and lines[1]:find('^[0-9:%.]* *execve%('))
|
||||||
|
or lines[1]:find('^__libc_start_main')
|
||||||
|
then
|
||||||
|
return 'strace'
|
||||||
|
end
|
||||||
|
end,
|
||||||
-- VSE JCL
|
-- VSE JCL
|
||||||
['^\\* $$ JOB\\>'] = { 'vsejcl', { vim_regex = true } },
|
['^\\* $$ JOB\\>'] = { 'vsejcl', { vim_regex = true } },
|
||||||
['^// *JOB\\>'] = { 'vsejcl', { vim_regex = true } },
|
['^// *JOB\\>'] = { 'vsejcl', { vim_regex = true } },
|
||||||
|
@@ -345,8 +345,10 @@ function M.normalize(path, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
path = path:gsub('\\', '/'):gsub('/+', '/')
|
path = path:gsub('\\', '/'):gsub('/+', '/')
|
||||||
|
if iswin and path:match('^%w:/$') then
|
||||||
return path:sub(-1) == '/' and path:sub(1, -2) or path
|
return path
|
||||||
|
end
|
||||||
|
return (path:gsub('(.)/$', '%1'))
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
@@ -20,6 +20,22 @@ function M.report_error(msg, ...)
|
|||||||
vim.fn['health#report_error'](msg, ...)
|
vim.fn['health#report_error'](msg, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.start(msg)
|
||||||
|
M.report_start(msg)
|
||||||
|
end
|
||||||
|
function M.info(msg)
|
||||||
|
M.report_info(msg)
|
||||||
|
end
|
||||||
|
function M.ok(msg)
|
||||||
|
M.report_ok(msg)
|
||||||
|
end
|
||||||
|
function M.warn(msg, ...)
|
||||||
|
M.report_warn(msg, ...)
|
||||||
|
end
|
||||||
|
function M.error(msg, ...)
|
||||||
|
M.report_error(msg, ...)
|
||||||
|
end
|
||||||
|
|
||||||
local path2name = function(path)
|
local path2name = function(path)
|
||||||
if path:match('%.lua$') then
|
if path:match('%.lua$') then
|
||||||
-- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
|
-- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
|
||||||
|
@@ -5,7 +5,7 @@ local loaders = package.loaders
|
|||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
---@alias CacheHash {mtime: {sec:number, nsec:number}, size:number, type: string}
|
---@alias CacheHash {mtime: {nsec: integer, sec: integer}, size: integer, type?: uv.aliases.fs_stat_types}
|
||||||
---@alias CacheEntry {hash:CacheHash, chunk:string}
|
---@alias CacheEntry {hash:CacheHash, chunk:string}
|
||||||
|
|
||||||
---@class ModuleFindOpts
|
---@class ModuleFindOpts
|
||||||
@@ -28,12 +28,11 @@ M.enabled = false
|
|||||||
---@field _rtp string[]
|
---@field _rtp string[]
|
||||||
---@field _rtp_pure string[]
|
---@field _rtp_pure string[]
|
||||||
---@field _rtp_key string
|
---@field _rtp_key string
|
||||||
|
---@field _hashes? table<string, CacheHash>
|
||||||
local Loader = {
|
local Loader = {
|
||||||
VERSION = 3,
|
VERSION = 3,
|
||||||
---@type table<string, table<string,ModuleInfo>>
|
---@type table<string, table<string,ModuleInfo>>
|
||||||
_indexed = {},
|
_indexed = {},
|
||||||
---@type table<string, CacheHash>
|
|
||||||
_hashes = {},
|
|
||||||
---@type table<string, string[]>
|
---@type table<string, string[]>
|
||||||
_topmods = {},
|
_topmods = {},
|
||||||
_loadfile = loadfile,
|
_loadfile = loadfile,
|
||||||
@@ -44,9 +43,13 @@ local Loader = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
--- @param path string
|
--- @param path string
|
||||||
--- @return uv.fs_stat.result
|
--- @return CacheHash
|
||||||
--- @private
|
--- @private
|
||||||
function Loader.get_hash(path)
|
function Loader.get_hash(path)
|
||||||
|
if not Loader._hashes then
|
||||||
|
return uv.fs_stat(path) --[[@as CacheHash]]
|
||||||
|
end
|
||||||
|
|
||||||
if not Loader._hashes[path] then
|
if not Loader._hashes[path] then
|
||||||
-- Note we must never save a stat for a non-existent path.
|
-- Note we must never save a stat for a non-existent path.
|
||||||
-- For non-existent paths fs_stat() will return nil.
|
-- For non-existent paths fs_stat() will return nil.
|
||||||
@@ -163,13 +166,16 @@ end
|
|||||||
---@return string|function
|
---@return string|function
|
||||||
---@private
|
---@private
|
||||||
function Loader.loader(modname)
|
function Loader.loader(modname)
|
||||||
|
Loader._hashes = {}
|
||||||
local ret = M.find(modname)[1]
|
local ret = M.find(modname)[1]
|
||||||
if ret then
|
if ret then
|
||||||
-- Make sure to call the global loadfile so we respect any augmentations done elsewhere.
|
-- Make sure to call the global loadfile so we respect any augmentations done elsewhere.
|
||||||
-- E.g. profiling
|
-- E.g. profiling
|
||||||
local chunk, err = loadfile(ret.modpath)
|
local chunk, err = loadfile(ret.modpath)
|
||||||
|
Loader._hashes = nil
|
||||||
return chunk or error(err)
|
return chunk or error(err)
|
||||||
end
|
end
|
||||||
|
Loader._hashes = nil
|
||||||
return '\ncache_loader: module ' .. modname .. ' not found'
|
return '\ncache_loader: module ' .. modname .. ' not found'
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -373,8 +379,10 @@ function M.reset(path)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Path could be a directory so just clear all the hashes.
|
-- Path could be a directory so just clear all the hashes.
|
||||||
|
if Loader._hashes then
|
||||||
Loader._hashes = {}
|
Loader._hashes = {}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Enables the experimental Lua module loader:
|
--- Enables the experimental Lua module loader:
|
||||||
--- * overrides loadfile
|
--- * overrides loadfile
|
||||||
|
@@ -933,8 +933,7 @@ end
|
|||||||
--- |vim.lsp.protocol.make_client_capabilities()|, passed to the language
|
--- |vim.lsp.protocol.make_client_capabilities()|, passed to the language
|
||||||
--- server on initialization. Hint: use make_client_capabilities() and modify
|
--- server on initialization. Hint: use make_client_capabilities() and modify
|
||||||
--- its result.
|
--- its result.
|
||||||
--- - Note: To send an empty dictionary use
|
--- - Note: To send an empty dictionary use |vim.empty_dict()|, else it will be encoded as an
|
||||||
--- `{[vim.type_idx]=vim.types.dictionary}`, else it will be encoded as an
|
|
||||||
--- array.
|
--- array.
|
||||||
---
|
---
|
||||||
--- - handlers: Map of language server method names to |lsp-handler|
|
--- - handlers: Map of language server method names to |lsp-handler|
|
||||||
|
@@ -193,21 +193,30 @@ local to_lsp_change_type = {
|
|||||||
function M.register(reg, ctx)
|
function M.register(reg, ctx)
|
||||||
local client_id = ctx.client_id
|
local client_id = ctx.client_id
|
||||||
local client = vim.lsp.get_client_by_id(client_id)
|
local client = vim.lsp.get_client_by_id(client_id)
|
||||||
if not client.workspace_folders then
|
-- Ill-behaved servers may not honor the client capability and try to register
|
||||||
|
-- anyway, so ignore requests when the user has opted out of the feature.
|
||||||
|
local has_capability = vim.tbl_get(
|
||||||
|
client.config.capabilities or {},
|
||||||
|
'workspace',
|
||||||
|
'didChangeWatchedFiles',
|
||||||
|
'dynamicRegistration'
|
||||||
|
)
|
||||||
|
if not has_capability or not client.workspace_folders then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local watch_regs = {}
|
local watch_regs = {}
|
||||||
for _, w in ipairs(reg.registerOptions.watchers) do
|
for _, w in ipairs(reg.registerOptions.watchers) do
|
||||||
|
local relative_pattern = false
|
||||||
local glob_patterns = {}
|
local glob_patterns = {}
|
||||||
if type(w.globPattern) == 'string' then
|
if type(w.globPattern) == 'string' then
|
||||||
for _, folder in ipairs(client.workspace_folders) do
|
for _, folder in ipairs(client.workspace_folders) do
|
||||||
table.insert(glob_patterns, { baseUri = folder.uri, pattern = w.globPattern })
|
table.insert(glob_patterns, { baseUri = folder.uri, pattern = w.globPattern })
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
relative_pattern = true
|
||||||
table.insert(glob_patterns, w.globPattern)
|
table.insert(glob_patterns, w.globPattern)
|
||||||
end
|
end
|
||||||
for _, glob_pattern in ipairs(glob_patterns) do
|
for _, glob_pattern in ipairs(glob_patterns) do
|
||||||
local pattern = parse(glob_pattern.pattern)
|
|
||||||
local base_dir = nil
|
local base_dir = nil
|
||||||
if type(glob_pattern.baseUri) == 'string' then
|
if type(glob_pattern.baseUri) == 'string' then
|
||||||
base_dir = glob_pattern.baseUri
|
base_dir = glob_pattern.baseUri
|
||||||
@@ -216,9 +225,16 @@ function M.register(reg, ctx)
|
|||||||
end
|
end
|
||||||
assert(base_dir, "couldn't identify root of watch")
|
assert(base_dir, "couldn't identify root of watch")
|
||||||
base_dir = vim.uri_to_fname(base_dir)
|
base_dir = vim.uri_to_fname(base_dir)
|
||||||
|
|
||||||
local kind = w.kind
|
local kind = w.kind
|
||||||
or protocol.WatchKind.Create + protocol.WatchKind.Change + protocol.WatchKind.Delete
|
or protocol.WatchKind.Create + protocol.WatchKind.Change + protocol.WatchKind.Delete
|
||||||
|
|
||||||
|
local pattern = glob_pattern.pattern
|
||||||
|
if relative_pattern then
|
||||||
|
pattern = base_dir .. '/' .. pattern
|
||||||
|
end
|
||||||
|
pattern = parse(pattern)
|
||||||
|
|
||||||
table.insert(watch_regs, {
|
table.insert(watch_regs, {
|
||||||
base_dir = base_dir,
|
base_dir = base_dir,
|
||||||
pattern = pattern,
|
pattern = pattern,
|
||||||
|
@@ -679,7 +679,7 @@ local function on_code_action_results(results, ctx, options)
|
|||||||
-- command: string
|
-- command: string
|
||||||
-- arguments?: any[]
|
-- arguments?: any[]
|
||||||
--
|
--
|
||||||
local client = vim.lsp.get_client_by_id(action_tuple[1])
|
local client = assert(vim.lsp.get_client_by_id(action_tuple[1]))
|
||||||
local action = action_tuple[2]
|
local action = action_tuple[2]
|
||||||
if
|
if
|
||||||
not action.edit
|
not action.edit
|
||||||
@@ -688,10 +688,14 @@ local function on_code_action_results(results, ctx, options)
|
|||||||
then
|
then
|
||||||
client.request('codeAction/resolve', action, function(err, resolved_action)
|
client.request('codeAction/resolve', action, function(err, resolved_action)
|
||||||
if err then
|
if err then
|
||||||
|
if action.command then
|
||||||
|
apply_action(action, client)
|
||||||
|
else
|
||||||
vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR)
|
vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR)
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
apply_action(resolved_action, client)
|
apply_action(resolved_action, client)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
apply_action(action, client)
|
apply_action(action, client)
|
||||||
|
@@ -135,6 +135,10 @@ end
|
|||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
---@param client_id integer
|
---@param client_id integer
|
||||||
function M.display(lenses, bufnr, client_id)
|
function M.display(lenses, bufnr, client_id)
|
||||||
|
if not api.nvim_buf_is_loaded(bufnr) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local ns = namespaces[client_id]
|
local ns = namespaces[client_id]
|
||||||
if not lenses or not next(lenses) then
|
if not lenses or not next(lenses) then
|
||||||
api.nvim_buf_clear_namespace(bufnr, ns, 0, -1)
|
api.nvim_buf_clear_namespace(bufnr, ns, 0, -1)
|
||||||
@@ -180,6 +184,10 @@ end
|
|||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
---@param client_id integer
|
---@param client_id integer
|
||||||
function M.save(lenses, bufnr, client_id)
|
function M.save(lenses, bufnr, client_id)
|
||||||
|
if not api.nvim_buf_is_loaded(bufnr) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local lenses_by_client = lens_cache_by_buf[bufnr]
|
local lenses_by_client = lens_cache_by_buf[bufnr]
|
||||||
if not lenses_by_client then
|
if not lenses_by_client then
|
||||||
lenses_by_client = {}
|
lenses_by_client = {}
|
||||||
@@ -220,11 +228,14 @@ local function resolve_lenses(lenses, bufnr, client_id, callback)
|
|||||||
countdown()
|
countdown()
|
||||||
else
|
else
|
||||||
client.request('codeLens/resolve', lens, function(_, result)
|
client.request('codeLens/resolve', lens, function(_, result)
|
||||||
if result and result.command then
|
if api.nvim_buf_is_loaded(bufnr) and result and result.command then
|
||||||
lens.command = result.command
|
lens.command = result.command
|
||||||
-- Eager display to have some sort of incremental feedback
|
-- Eager display to have some sort of incremental feedback
|
||||||
-- Once all lenses got resolved there will be a full redraw for all lenses
|
-- Once all lenses got resolved there will be a full redraw for all lenses
|
||||||
-- So that multiple lens per line are properly displayed
|
-- So that multiple lens per line are properly displayed
|
||||||
|
|
||||||
|
local num_lines = api.nvim_buf_line_count(bufnr)
|
||||||
|
if lens.range.start.line <= num_lines then
|
||||||
api.nvim_buf_set_extmark(
|
api.nvim_buf_set_extmark(
|
||||||
bufnr,
|
bufnr,
|
||||||
ns,
|
ns,
|
||||||
@@ -233,6 +244,8 @@ local function resolve_lenses(lenses, bufnr, client_id, callback)
|
|||||||
{ virt_text = { { lens.command.title, 'LspCodeLens' } }, hl_mode = 'combine' }
|
{ virt_text = { { lens.command.title, 'LspCodeLens' } }, hl_mode = 'combine' }
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
countdown()
|
countdown()
|
||||||
end, bufnr)
|
end, bufnr)
|
||||||
end
|
end
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
local api = vim.api
|
local api = vim.api
|
||||||
|
local bit = require('bit')
|
||||||
local handlers = require('vim.lsp.handlers')
|
local handlers = require('vim.lsp.handlers')
|
||||||
local util = require('vim.lsp.util')
|
local util = require('vim.lsp.util')
|
||||||
local bit = require('bit')
|
local uv = vim.loop
|
||||||
|
|
||||||
--- @class STTokenRange
|
--- @class STTokenRange
|
||||||
--- @field line integer line number 0-based
|
--- @field line integer line number 0-based
|
||||||
@@ -94,15 +95,39 @@ end
|
|||||||
---
|
---
|
||||||
---@private
|
---@private
|
||||||
---@return STTokenRange[]
|
---@return STTokenRange[]
|
||||||
local function tokens_to_ranges(data, bufnr, client)
|
local function tokens_to_ranges(data, bufnr, client, request)
|
||||||
local legend = client.server_capabilities.semanticTokensProvider.legend
|
local legend = client.server_capabilities.semanticTokensProvider.legend
|
||||||
local token_types = legend.tokenTypes
|
local token_types = legend.tokenTypes
|
||||||
local token_modifiers = legend.tokenModifiers
|
local token_modifiers = legend.tokenModifiers
|
||||||
|
local lines = api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||||
local ranges = {}
|
local ranges = {}
|
||||||
|
|
||||||
|
local start = uv.hrtime()
|
||||||
|
local ms_to_ns = 1000 * 1000
|
||||||
|
local yield_interval_ns = 5 * ms_to_ns
|
||||||
|
local co, is_main = coroutine.running()
|
||||||
|
|
||||||
local line
|
local line
|
||||||
local start_char = 0
|
local start_char = 0
|
||||||
for i = 1, #data, 5 do
|
for i = 1, #data, 5 do
|
||||||
|
-- if this function is called from the main coroutine, let it run to completion with no yield
|
||||||
|
if not is_main then
|
||||||
|
local elapsed_ns = uv.hrtime() - start
|
||||||
|
|
||||||
|
if elapsed_ns > yield_interval_ns then
|
||||||
|
vim.schedule(function()
|
||||||
|
coroutine.resume(co, util.buf_versions[bufnr])
|
||||||
|
end)
|
||||||
|
if request.version ~= coroutine.yield() then
|
||||||
|
-- request became stale since the last time the coroutine ran.
|
||||||
|
-- abandon it by yielding without a way to resume
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
|
||||||
|
start = uv.hrtime()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local delta_line = data[i]
|
local delta_line = data[i]
|
||||||
line = line and line + delta_line or delta_line
|
line = line and line + delta_line or delta_line
|
||||||
local delta_start = data[i + 1]
|
local delta_start = data[i + 1]
|
||||||
@@ -113,11 +138,17 @@ local function tokens_to_ranges(data, bufnr, client)
|
|||||||
local modifiers = modifiers_from_number(data[i + 4], token_modifiers)
|
local modifiers = modifiers_from_number(data[i + 4], token_modifiers)
|
||||||
|
|
||||||
---@private
|
---@private
|
||||||
local function _get_byte_pos(char_pos)
|
local function _get_byte_pos(col)
|
||||||
return util._get_line_byte_from_position(bufnr, {
|
if col > 0 then
|
||||||
line = line,
|
local buf_line = lines[line + 1] or ''
|
||||||
character = char_pos,
|
local ok, result
|
||||||
}, client.offset_encoding)
|
ok, result = pcall(util._str_byteindex_enc, buf_line, col, client.offset_encoding)
|
||||||
|
if ok then
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
return math.min(#buf_line, col)
|
||||||
|
end
|
||||||
|
return col
|
||||||
end
|
end
|
||||||
|
|
||||||
local start_col = _get_byte_pos(start_char)
|
local start_col = _get_byte_pos(start_char)
|
||||||
@@ -280,7 +311,7 @@ function STHighlighter:send_request()
|
|||||||
local c = vim.lsp.get_client_by_id(ctx.client_id)
|
local c = vim.lsp.get_client_by_id(ctx.client_id)
|
||||||
local highlighter = STHighlighter.active[ctx.bufnr]
|
local highlighter = STHighlighter.active[ctx.bufnr]
|
||||||
if not err and c and highlighter then
|
if not err and c and highlighter then
|
||||||
highlighter:process_response(response, c, version)
|
coroutine.wrap(STHighlighter.process_response)(highlighter, response, c, version)
|
||||||
end
|
end
|
||||||
end, self.bufnr)
|
end, self.bufnr)
|
||||||
|
|
||||||
@@ -315,11 +346,9 @@ function STHighlighter:process_response(response, client, version)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- reset active request
|
|
||||||
state.active_request = {}
|
|
||||||
|
|
||||||
-- skip nil responses
|
-- skip nil responses
|
||||||
if response == nil then
|
if response == nil then
|
||||||
|
state.active_request = {}
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -347,12 +376,19 @@ function STHighlighter:process_response(response, client, version)
|
|||||||
tokens = response.data
|
tokens = response.data
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update the state with the new results
|
-- convert token list to highlight ranges
|
||||||
|
-- this could yield and run over multiple event loop iterations
|
||||||
|
local highlights = tokens_to_ranges(tokens, self.bufnr, client, state.active_request)
|
||||||
|
|
||||||
|
-- reset active request
|
||||||
|
state.active_request = {}
|
||||||
|
|
||||||
|
-- update the state with the new results
|
||||||
local current_result = state.current_result
|
local current_result = state.current_result
|
||||||
current_result.version = version
|
current_result.version = version
|
||||||
current_result.result_id = response.resultId
|
current_result.result_id = response.resultId
|
||||||
current_result.tokens = tokens
|
current_result.tokens = tokens
|
||||||
current_result.highlights = tokens_to_ranges(tokens, self.bufnr, client)
|
current_result.highlights = highlights
|
||||||
current_result.namespace_cleared = false
|
current_result.namespace_cleared = false
|
||||||
|
|
||||||
-- redraw all windows displaying buffer
|
-- redraw all windows displaying buffer
|
||||||
|
@@ -253,12 +253,17 @@ local function get_lines(bufnr, rows)
|
|||||||
---@private
|
---@private
|
||||||
local function buf_lines()
|
local function buf_lines()
|
||||||
local lines = {}
|
local lines = {}
|
||||||
for _, row in pairs(rows) do
|
for _, row in ipairs(rows) do
|
||||||
lines[row] = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { '' })[1]
|
lines[row] = (api.nvim_buf_get_lines(bufnr, row, row + 1, false) or { '' })[1]
|
||||||
end
|
end
|
||||||
return lines
|
return lines
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- use loaded buffers if available
|
||||||
|
if vim.fn.bufloaded(bufnr) == 1 then
|
||||||
|
return buf_lines()
|
||||||
|
end
|
||||||
|
|
||||||
local uri = vim.uri_from_bufnr(bufnr)
|
local uri = vim.uri_from_bufnr(bufnr)
|
||||||
|
|
||||||
-- load the buffer if this is not a file uri
|
-- load the buffer if this is not a file uri
|
||||||
@@ -268,11 +273,6 @@ local function get_lines(bufnr, rows)
|
|||||||
return buf_lines()
|
return buf_lines()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- use loaded buffers if available
|
|
||||||
if vim.fn.bufloaded(bufnr) == 1 then
|
|
||||||
return buf_lines()
|
|
||||||
end
|
|
||||||
|
|
||||||
local filename = api.nvim_buf_get_name(bufnr)
|
local filename = api.nvim_buf_get_name(bufnr)
|
||||||
|
|
||||||
-- get the data from the file
|
-- get the data from the file
|
||||||
|
@@ -100,10 +100,9 @@ function vim.gsplit(s, sep, opts)
|
|||||||
local start = 1
|
local start = 1
|
||||||
local done = false
|
local done = false
|
||||||
|
|
||||||
-- For `trimempty`:
|
-- For `trimempty`: queue of collected segments, to be emitted at next pass.
|
||||||
|
local segs = {}
|
||||||
local empty_start = true -- Only empty segments seen so far.
|
local empty_start = true -- Only empty segments seen so far.
|
||||||
local empty_segs = 0 -- Empty segments found between non-empty segments.
|
|
||||||
local nonemptyseg = nil
|
|
||||||
|
|
||||||
local function _pass(i, j, ...)
|
local function _pass(i, j, ...)
|
||||||
if i then
|
if i then
|
||||||
@@ -118,14 +117,9 @@ function vim.gsplit(s, sep, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
return function()
|
return function()
|
||||||
if trimempty and empty_segs > 0 then
|
if trimempty and #segs > 0 then
|
||||||
-- trimempty: Pop the collected empty segments.
|
-- trimempty: Pop the collected segments.
|
||||||
empty_segs = empty_segs - 1
|
return table.remove(segs)
|
||||||
return ''
|
|
||||||
elseif trimempty and nonemptyseg then
|
|
||||||
local seg = nonemptyseg
|
|
||||||
nonemptyseg = nil
|
|
||||||
return seg
|
|
||||||
elseif done or (s == '' and sep == '') then
|
elseif done or (s == '' and sep == '') then
|
||||||
return nil
|
return nil
|
||||||
elseif sep == '' then
|
elseif sep == '' then
|
||||||
@@ -138,21 +132,24 @@ function vim.gsplit(s, sep, opts)
|
|||||||
local seg = _pass(s:find(sep, start, plain))
|
local seg = _pass(s:find(sep, start, plain))
|
||||||
|
|
||||||
-- Trim empty segments from start/end.
|
-- Trim empty segments from start/end.
|
||||||
if trimempty and seg == '' then
|
if trimempty and seg ~= '' then
|
||||||
|
empty_start = false
|
||||||
|
elseif trimempty and seg == '' then
|
||||||
while not done and seg == '' do
|
while not done and seg == '' do
|
||||||
empty_segs = empty_segs + 1
|
table.insert(segs, 1, '')
|
||||||
seg = _pass(s:find(sep, start, plain))
|
seg = _pass(s:find(sep, start, plain))
|
||||||
end
|
end
|
||||||
if done and seg == '' then
|
if done and seg == '' then
|
||||||
return nil
|
return nil
|
||||||
elseif empty_start then
|
elseif empty_start then
|
||||||
empty_start = false
|
empty_start = false
|
||||||
empty_segs = 0
|
segs = {}
|
||||||
return seg
|
return seg
|
||||||
end
|
end
|
||||||
nonemptyseg = seg ~= '' and seg or nil
|
if seg ~= '' then
|
||||||
seg = ''
|
table.insert(segs, 1, seg)
|
||||||
empty_segs = empty_segs - 1
|
end
|
||||||
|
return table.remove(segs)
|
||||||
end
|
end
|
||||||
|
|
||||||
return seg
|
return seg
|
||||||
|
@@ -136,16 +136,6 @@ function M.get_parser(bufnr, lang, opts)
|
|||||||
return parsers[bufnr]
|
return parsers[bufnr]
|
||||||
end
|
end
|
||||||
|
|
||||||
---@package
|
|
||||||
---@param bufnr (integer|nil) Buffer number
|
|
||||||
---@return boolean
|
|
||||||
function M._has_parser(bufnr)
|
|
||||||
if bufnr == nil or bufnr == 0 then
|
|
||||||
bufnr = api.nvim_get_current_buf()
|
|
||||||
end
|
|
||||||
return parsers[bufnr] ~= nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Returns a string parser
|
--- Returns a string parser
|
||||||
---
|
---
|
||||||
---@param str string Text to parse
|
---@param str string Text to parse
|
||||||
|
@@ -32,15 +32,58 @@ function FoldInfo:invalidate_range(srow, erow)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Efficiently remove items from middle of a list a list.
|
||||||
|
---
|
||||||
|
--- Calling table.remove() in a loop will re-index the tail of the table on
|
||||||
|
--- every iteration, instead this function will re-index the table exactly
|
||||||
|
--- once.
|
||||||
|
---
|
||||||
|
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
|
||||||
|
---
|
||||||
|
---@param t any[]
|
||||||
|
---@param first integer
|
||||||
|
---@param last integer
|
||||||
|
local function list_remove(t, first, last)
|
||||||
|
local n = #t
|
||||||
|
for i = 0, n - first do
|
||||||
|
t[first + i] = t[last + 1 + i]
|
||||||
|
t[last + 1 + i] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@package
|
---@package
|
||||||
---@param srow integer
|
---@param srow integer
|
||||||
---@param erow integer
|
---@param erow integer
|
||||||
function FoldInfo:remove_range(srow, erow)
|
function FoldInfo:remove_range(srow, erow)
|
||||||
for i = erow - 1, srow, -1 do
|
list_remove(self.levels, srow + 1, erow)
|
||||||
table.remove(self.levels, i + 1)
|
list_remove(self.levels0, srow + 1, erow)
|
||||||
table.remove(self.levels0, i + 1)
|
list_remove(self.start_counts, srow + 1, erow)
|
||||||
table.remove(self.start_counts, i + 1)
|
list_remove(self.stop_counts, srow + 1, erow)
|
||||||
table.remove(self.stop_counts, i + 1)
|
end
|
||||||
|
|
||||||
|
--- Efficiently insert items into the middle of a list.
|
||||||
|
---
|
||||||
|
--- Calling table.insert() in a loop will re-index the tail of the table on
|
||||||
|
--- every iteration, instead this function will re-index the table exactly
|
||||||
|
--- once.
|
||||||
|
---
|
||||||
|
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
|
||||||
|
---
|
||||||
|
---@param t any[]
|
||||||
|
---@param first integer
|
||||||
|
---@param last integer
|
||||||
|
---@param v any
|
||||||
|
local function list_insert(t, first, last, v)
|
||||||
|
local n = #t
|
||||||
|
|
||||||
|
-- Shift table forward
|
||||||
|
for i = n - first, 0, -1 do
|
||||||
|
t[last + 1 + i] = t[first + i]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Fill in new values
|
||||||
|
for i = first, last do
|
||||||
|
t[i] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -48,12 +91,10 @@ end
|
|||||||
---@param srow integer
|
---@param srow integer
|
||||||
---@param erow integer
|
---@param erow integer
|
||||||
function FoldInfo:add_range(srow, erow)
|
function FoldInfo:add_range(srow, erow)
|
||||||
for i = srow, erow - 1 do
|
list_insert(self.levels, srow + 1, erow, '-1')
|
||||||
table.insert(self.levels, i + 1, '-1')
|
list_insert(self.levels0, srow + 1, erow, -1)
|
||||||
table.insert(self.levels0, i + 1, -1)
|
list_insert(self.start_counts, srow + 1, erow, nil)
|
||||||
table.insert(self.start_counts, i + 1, nil)
|
list_insert(self.stop_counts, srow + 1, erow, nil)
|
||||||
table.insert(self.stop_counts, i + 1, nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@package
|
---@package
|
||||||
@@ -184,13 +225,25 @@ local function recompute_folds()
|
|||||||
vim._foldupdate()
|
vim._foldupdate()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Schedule a function only if bufnr is loaded
|
||||||
|
---@param bufnr integer
|
||||||
|
---@param fn function
|
||||||
|
local function schedule_if_loaded(bufnr, fn)
|
||||||
|
vim.schedule(function()
|
||||||
|
if not api.nvim_buf_is_loaded(bufnr) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
fn()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
---@param foldinfo TS.FoldInfo
|
---@param foldinfo TS.FoldInfo
|
||||||
---@param tree_changes Range4[]
|
---@param tree_changes Range4[]
|
||||||
local function on_changedtree(bufnr, foldinfo, tree_changes)
|
local function on_changedtree(bufnr, foldinfo, tree_changes)
|
||||||
-- For some reason, queries seem to use the old buffer state in on_bytes.
|
-- For some reason, queries seem to use the old buffer state in on_bytes.
|
||||||
-- Get around this by scheduling and manually updating folds.
|
-- Get around this by scheduling and manually updating folds.
|
||||||
vim.schedule(function()
|
schedule_if_loaded(bufnr, function()
|
||||||
for _, change in ipairs(tree_changes) do
|
for _, change in ipairs(tree_changes) do
|
||||||
local srow, _, erow = Range.unpack4(change)
|
local srow, _, erow = Range.unpack4(change)
|
||||||
get_folds_levels(bufnr, foldinfo, srow, erow)
|
get_folds_levels(bufnr, foldinfo, srow, erow)
|
||||||
@@ -212,7 +265,7 @@ local function on_bytes(bufnr, foldinfo, start_row, old_row, new_row)
|
|||||||
foldinfo:remove_range(end_row_new, end_row_old)
|
foldinfo:remove_range(end_row_new, end_row_old)
|
||||||
elseif new_row > old_row then
|
elseif new_row > old_row then
|
||||||
foldinfo:add_range(start_row, end_row_new)
|
foldinfo:add_range(start_row, end_row_new)
|
||||||
vim.schedule(function()
|
schedule_if_loaded(bufnr, function()
|
||||||
get_folds_levels(bufnr, foldinfo, start_row, end_row_new)
|
get_folds_levels(bufnr, foldinfo, start_row, end_row_new)
|
||||||
recompute_folds()
|
recompute_folds()
|
||||||
end)
|
end)
|
||||||
@@ -226,7 +279,8 @@ function M.foldexpr(lnum)
|
|||||||
lnum = lnum or vim.v.lnum
|
lnum = lnum or vim.v.lnum
|
||||||
local bufnr = api.nvim_get_current_buf()
|
local bufnr = api.nvim_get_current_buf()
|
||||||
|
|
||||||
if not vim.treesitter._has_parser(bufnr) or not lnum then
|
local parser = vim.F.npcall(vim.treesitter.get_parser, bufnr)
|
||||||
|
if not parser then
|
||||||
return '0'
|
return '0'
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -234,7 +288,6 @@ function M.foldexpr(lnum)
|
|||||||
foldinfos[bufnr] = FoldInfo.new()
|
foldinfos[bufnr] = FoldInfo.new()
|
||||||
get_folds_levels(bufnr, foldinfos[bufnr])
|
get_folds_levels(bufnr, foldinfos[bufnr])
|
||||||
|
|
||||||
local parser = vim.treesitter.get_parser(bufnr)
|
|
||||||
parser:register_cbs({
|
parser:register_cbs({
|
||||||
on_changedtree = function(tree_changes)
|
on_changedtree = function(tree_changes)
|
||||||
on_changedtree(bufnr, foldinfos[bufnr], tree_changes)
|
on_changedtree(bufnr, foldinfos[bufnr], tree_changes)
|
||||||
|
@@ -76,9 +76,6 @@ function TSHighlighter.new(tree, opts)
|
|||||||
opts = opts or {} ---@type { queries: table<string,string> }
|
opts = opts or {} ---@type { queries: table<string,string> }
|
||||||
self.tree = tree
|
self.tree = tree
|
||||||
tree:register_cbs({
|
tree:register_cbs({
|
||||||
on_changedtree = function(...)
|
|
||||||
self:on_changedtree(...)
|
|
||||||
end,
|
|
||||||
on_bytes = function(...)
|
on_bytes = function(...)
|
||||||
self:on_bytes(...)
|
self:on_bytes(...)
|
||||||
end,
|
end,
|
||||||
@@ -87,6 +84,17 @@ function TSHighlighter.new(tree, opts)
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
tree:register_cbs({
|
||||||
|
on_changedtree = function(...)
|
||||||
|
self:on_changedtree(...)
|
||||||
|
end,
|
||||||
|
on_child_removed = function(child)
|
||||||
|
child:for_each_tree(function(t)
|
||||||
|
self:on_changedtree(t:included_ranges(true))
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
}, true)
|
||||||
|
|
||||||
self.bufnr = tree:source() --[[@as integer]]
|
self.bufnr = tree:source() --[[@as integer]]
|
||||||
self.edit_count = 0
|
self.edit_count = 0
|
||||||
self.redraw_count = 0
|
self.redraw_count = 0
|
||||||
@@ -177,10 +185,10 @@ function TSHighlighter:on_detach()
|
|||||||
end
|
end
|
||||||
|
|
||||||
---@package
|
---@package
|
||||||
---@param changes integer[][]?
|
---@param changes Range6[][]
|
||||||
function TSHighlighter:on_changedtree(changes)
|
function TSHighlighter:on_changedtree(changes)
|
||||||
for _, ch in ipairs(changes or {}) do
|
for _, ch in ipairs(changes) do
|
||||||
api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[3] + 1)
|
api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[4] + 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -77,9 +77,8 @@ function M.add(lang, opts)
|
|||||||
filetype = { filetype, { 'string', 'table' }, true },
|
filetype = { filetype, { 'string', 'table' }, true },
|
||||||
})
|
})
|
||||||
|
|
||||||
M.register(lang, filetype)
|
|
||||||
|
|
||||||
if vim._ts_has_language(lang) then
|
if vim._ts_has_language(lang) then
|
||||||
|
M.register(lang, filetype)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -97,6 +96,7 @@ function M.add(lang, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
vim._ts_add_language(path, lang, symbol_name)
|
vim._ts_add_language(path, lang, symbol_name)
|
||||||
|
M.register(lang, filetype)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @private
|
--- @private
|
||||||
|
@@ -51,8 +51,18 @@ local Range = require('vim.treesitter._range')
|
|||||||
---| 'on_child_added'
|
---| 'on_child_added'
|
||||||
---| 'on_child_removed'
|
---| 'on_child_removed'
|
||||||
|
|
||||||
|
--- @type table<TSCallbackNameOn,TSCallbackName>
|
||||||
|
local TSCallbackNames = {
|
||||||
|
on_changedtree = 'changedtree',
|
||||||
|
on_bytes = 'bytes',
|
||||||
|
on_detach = 'detach',
|
||||||
|
on_child_added = 'child_added',
|
||||||
|
on_child_removed = 'child_removed',
|
||||||
|
}
|
||||||
|
|
||||||
---@class LanguageTree
|
---@class LanguageTree
|
||||||
---@field private _callbacks table<TSCallbackName,function[]> Callback handlers
|
---@field private _callbacks table<TSCallbackName,function[]> Callback handlers
|
||||||
|
---@field package _callbacks_rec table<TSCallbackName,function[]> Callback handlers (recursive)
|
||||||
---@field private _children table<string,LanguageTree> Injected languages
|
---@field private _children table<string,LanguageTree> Injected languages
|
||||||
---@field private _injection_query Query Queries defining injected languages
|
---@field private _injection_query Query Queries defining injected languages
|
||||||
---@field private _opts table Options
|
---@field private _opts table Options
|
||||||
@@ -79,7 +89,7 @@ LanguageTree.__index = LanguageTree
|
|||||||
--- "injected" language parsers, which themselves may inject other languages, recursively.
|
--- "injected" language parsers, which themselves may inject other languages, recursively.
|
||||||
---
|
---
|
||||||
---@param source (integer|string) Buffer or text string to parse
|
---@param source (integer|string) Buffer or text string to parse
|
||||||
---@param lang string|nil Root language of this tree
|
---@param lang string Root language of this tree
|
||||||
---@param opts (table|nil) Optional arguments:
|
---@param opts (table|nil) Optional arguments:
|
||||||
--- - injections table Map of language to injection query strings. Overrides the
|
--- - injections table Map of language to injection query strings. Overrides the
|
||||||
--- built-in runtime file searching for language injections.
|
--- built-in runtime file searching for language injections.
|
||||||
@@ -89,6 +99,10 @@ function LanguageTree.new(source, lang, opts)
|
|||||||
---@type LanguageTreeOpts
|
---@type LanguageTreeOpts
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
|
if source == 0 then
|
||||||
|
source = vim.api.nvim_get_current_buf()
|
||||||
|
end
|
||||||
|
|
||||||
local injections = opts.injections or {}
|
local injections = opts.injections or {}
|
||||||
local self = setmetatable({
|
local self = setmetatable({
|
||||||
_source = source,
|
_source = source,
|
||||||
@@ -100,15 +114,15 @@ function LanguageTree.new(source, lang, opts)
|
|||||||
or query.get(lang, 'injections'),
|
or query.get(lang, 'injections'),
|
||||||
_valid = false,
|
_valid = false,
|
||||||
_parser = vim._create_ts_parser(lang),
|
_parser = vim._create_ts_parser(lang),
|
||||||
_callbacks = {
|
_callbacks = {},
|
||||||
changedtree = {},
|
_callbacks_rec = {},
|
||||||
bytes = {},
|
|
||||||
detach = {},
|
|
||||||
child_added = {},
|
|
||||||
child_removed = {},
|
|
||||||
},
|
|
||||||
}, LanguageTree)
|
}, LanguageTree)
|
||||||
|
|
||||||
|
for _, name in pairs(TSCallbackNames) do
|
||||||
|
self._callbacks[name] = {}
|
||||||
|
self._callbacks_rec[name] = {}
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -121,6 +135,7 @@ local function tcall(f, ...)
|
|||||||
local start = vim.loop.hrtime()
|
local start = vim.loop.hrtime()
|
||||||
---@diagnostic disable-next-line
|
---@diagnostic disable-next-line
|
||||||
local r = { f(...) }
|
local r = { f(...) }
|
||||||
|
--- @type number
|
||||||
local duration = (vim.loop.hrtime() - start) / 1000000
|
local duration = (vim.loop.hrtime() - start) / 1000000
|
||||||
return duration, unpack(r)
|
return duration, unpack(r)
|
||||||
end
|
end
|
||||||
@@ -161,6 +176,9 @@ function LanguageTree:invalidate(reload)
|
|||||||
|
|
||||||
-- buffer was reloaded, reparse all trees
|
-- buffer was reloaded, reparse all trees
|
||||||
if reload then
|
if reload then
|
||||||
|
for _, t in ipairs(self._trees) do
|
||||||
|
self:_do_callback('changedtree', t:included_ranges(true), t)
|
||||||
|
end
|
||||||
self._trees = {}
|
self._trees = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -245,9 +263,12 @@ function LanguageTree:parse()
|
|||||||
if not self._valid or not self._valid[i] then
|
if not self._valid or not self._valid[i] then
|
||||||
self._parser:set_included_ranges(ranges)
|
self._parser:set_included_ranges(ranges)
|
||||||
local parse_time, tree, tree_changes =
|
local parse_time, tree, tree_changes =
|
||||||
tcall(self._parser.parse, self._parser, self._trees[i], self._source)
|
tcall(self._parser.parse, self._parser, self._trees[i], self._source, true)
|
||||||
|
|
||||||
self:_do_callback('changedtree', tree_changes, tree)
|
-- Pass ranges if this is an initial parse
|
||||||
|
local cb_changes = self._trees[i] and tree_changes or ranges
|
||||||
|
|
||||||
|
self:_do_callback('changedtree', cb_changes, tree)
|
||||||
self._trees[i] = tree
|
self._trees[i] = tree
|
||||||
vim.list_extend(changes, tree_changes)
|
vim.list_extend(changes, tree_changes)
|
||||||
|
|
||||||
@@ -291,9 +312,9 @@ function LanguageTree:parse()
|
|||||||
query_time = query_time,
|
query_time = query_time,
|
||||||
})
|
})
|
||||||
|
|
||||||
self:for_each_child(function(child)
|
for _, child in pairs(self._children) do
|
||||||
child:parse()
|
child:parse()
|
||||||
end)
|
end
|
||||||
|
|
||||||
self._valid = true
|
self._valid = true
|
||||||
|
|
||||||
@@ -341,7 +362,14 @@ function LanguageTree:add_child(lang)
|
|||||||
self:remove_child(lang)
|
self:remove_child(lang)
|
||||||
end
|
end
|
||||||
|
|
||||||
self._children[lang] = LanguageTree.new(self._source, lang, self._opts)
|
local child = LanguageTree.new(self._source, lang, self._opts)
|
||||||
|
|
||||||
|
-- Inherit recursive callbacks
|
||||||
|
for nm, cb in pairs(self._callbacks_rec) do
|
||||||
|
vim.list_extend(child._callbacks_rec[nm], cb)
|
||||||
|
end
|
||||||
|
|
||||||
|
self._children[lang] = child
|
||||||
self:invalidate()
|
self:invalidate()
|
||||||
self:_do_callback('child_added', self._children[lang])
|
self:_do_callback('child_added', self._children[lang])
|
||||||
|
|
||||||
@@ -453,6 +481,10 @@ function LanguageTree:set_included_regions(new_regions)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if #self:included_regions() ~= #new_regions then
|
if #self:included_regions() ~= #new_regions then
|
||||||
|
-- TODO(lewis6991): inefficient; invalidate trees incrementally
|
||||||
|
for _, t in ipairs(self._trees) do
|
||||||
|
self:_do_callback('changedtree', t:included_ranges(true), t)
|
||||||
|
end
|
||||||
self._trees = {}
|
self._trees = {}
|
||||||
self:invalidate()
|
self:invalidate()
|
||||||
else
|
else
|
||||||
@@ -489,11 +521,13 @@ end
|
|||||||
---@param node TSNode
|
---@param node TSNode
|
||||||
---@param source string|integer
|
---@param source string|integer
|
||||||
---@param metadata TSMetadata
|
---@param metadata TSMetadata
|
||||||
|
---@param include_children boolean
|
||||||
---@return Range6[]
|
---@return Range6[]
|
||||||
local function get_node_ranges(node, source, metadata, include_children)
|
local function get_node_ranges(node, source, metadata, include_children)
|
||||||
local range = vim.treesitter.get_range(node, source, metadata)
|
local range = vim.treesitter.get_range(node, source, metadata)
|
||||||
|
local child_count = node:named_child_count()
|
||||||
|
|
||||||
if include_children then
|
if include_children or child_count == 0 then
|
||||||
return { range }
|
return { range }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -501,7 +535,8 @@ local function get_node_ranges(node, source, metadata, include_children)
|
|||||||
|
|
||||||
local srow, scol, sbyte, erow, ecol, ebyte = Range.unpack6(range)
|
local srow, scol, sbyte, erow, ecol, ebyte = Range.unpack6(range)
|
||||||
|
|
||||||
for i = 0, node:named_child_count() - 1 do
|
-- We are excluding children so we need to mask out their ranges
|
||||||
|
for i = 0, child_count - 1 do
|
||||||
local child = node:named_child(i)
|
local child = node:named_child(i)
|
||||||
local c_srow, c_scol, c_sbyte, c_erow, c_ecol, c_ebyte = child:range(true)
|
local c_srow, c_scol, c_sbyte, c_erow, c_ecol, c_ebyte = child:range(true)
|
||||||
if c_srow > srow or c_scol > scol then
|
if c_srow > srow or c_scol > scol then
|
||||||
@@ -533,7 +568,10 @@ end
|
|||||||
---@param combined boolean
|
---@param combined boolean
|
||||||
---@param ranges Range6[]
|
---@param ranges Range6[]
|
||||||
local function add_injection(t, tree_index, pattern, lang, combined, ranges)
|
local function add_injection(t, tree_index, pattern, lang, combined, ranges)
|
||||||
assert(type(lang) == 'string')
|
if #ranges == 0 then
|
||||||
|
-- Make sure not to add an empty range set as this is interpreted to mean the whole buffer.
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Each tree index should be isolated from the other nodes.
|
-- Each tree index should be isolated from the other nodes.
|
||||||
if not t[tree_index] then
|
if not t[tree_index] then
|
||||||
@@ -707,6 +745,9 @@ function LanguageTree:_do_callback(cb_name, ...)
|
|||||||
for _, cb in ipairs(self._callbacks[cb_name]) do
|
for _, cb in ipairs(self._callbacks[cb_name]) do
|
||||||
cb(...)
|
cb(...)
|
||||||
end
|
end
|
||||||
|
for _, cb in ipairs(self._callbacks_rec[cb_name]) do
|
||||||
|
cb(...)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@package
|
---@package
|
||||||
@@ -759,6 +800,20 @@ function LanguageTree:_edit(
|
|||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
for _, child in pairs(self._children) do
|
||||||
|
child:_edit(
|
||||||
|
start_byte,
|
||||||
|
end_byte_old,
|
||||||
|
end_byte_new,
|
||||||
|
start_row,
|
||||||
|
start_col,
|
||||||
|
end_row_old,
|
||||||
|
end_col_old,
|
||||||
|
end_row_new,
|
||||||
|
end_col_new
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@package
|
---@package
|
||||||
@@ -805,9 +860,7 @@ function LanguageTree:_on_bytes(
|
|||||||
)
|
)
|
||||||
|
|
||||||
-- Edit trees together BEFORE emitting a bytes callback.
|
-- Edit trees together BEFORE emitting a bytes callback.
|
||||||
---@private
|
self:_edit(
|
||||||
self:for_each_child(function(child)
|
|
||||||
child:_edit(
|
|
||||||
start_byte,
|
start_byte,
|
||||||
start_byte + old_byte,
|
start_byte + old_byte,
|
||||||
start_byte + new_byte,
|
start_byte + new_byte,
|
||||||
@@ -818,7 +871,6 @@ function LanguageTree:_on_bytes(
|
|||||||
start_row + new_row,
|
start_row + new_row,
|
||||||
new_end_col
|
new_end_col
|
||||||
)
|
)
|
||||||
end, true)
|
|
||||||
|
|
||||||
self:_do_callback(
|
self:_do_callback(
|
||||||
'bytes',
|
'bytes',
|
||||||
@@ -855,30 +907,26 @@ end
|
|||||||
--- changed.
|
--- changed.
|
||||||
--- - `on_child_added` : emitted when a child is added to the tree.
|
--- - `on_child_added` : emitted when a child is added to the tree.
|
||||||
--- - `on_child_removed` : emitted when a child is removed from the tree.
|
--- - `on_child_removed` : emitted when a child is removed from the tree.
|
||||||
function LanguageTree:register_cbs(cbs)
|
--- @param recursive? boolean Apply callbacks recursively for all children. Any new children will
|
||||||
|
--- also inherit the callbacks.
|
||||||
|
function LanguageTree:register_cbs(cbs, recursive)
|
||||||
---@cast cbs table<TSCallbackNameOn,function>
|
---@cast cbs table<TSCallbackNameOn,function>
|
||||||
if not cbs then
|
if not cbs then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if cbs.on_changedtree then
|
local callbacks = recursive and self._callbacks_rec or self._callbacks
|
||||||
table.insert(self._callbacks.changedtree, cbs.on_changedtree)
|
|
||||||
|
for name, cbname in pairs(TSCallbackNames) do
|
||||||
|
if cbs[name] then
|
||||||
|
table.insert(callbacks[cbname], cbs[name])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if cbs.on_bytes then
|
if recursive then
|
||||||
table.insert(self._callbacks.bytes, cbs.on_bytes)
|
for _, child in pairs(self._children) do
|
||||||
|
child:register_cbs(cbs, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
if cbs.on_detach then
|
|
||||||
table.insert(self._callbacks.detach, cbs.on_detach)
|
|
||||||
end
|
|
||||||
|
|
||||||
if cbs.on_child_added then
|
|
||||||
table.insert(self._callbacks.child_added, cbs.on_child_added)
|
|
||||||
end
|
|
||||||
|
|
||||||
if cbs.on_child_removed then
|
|
||||||
table.insert(self._callbacks.child_removed, cbs.on_child_removed)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -102,18 +102,18 @@ function TSPlayground:new(bufnr, lang)
|
|||||||
-- the root in the child tree to the {injections} table.
|
-- the root in the child tree to the {injections} table.
|
||||||
local root = parser:parse()[1]:root()
|
local root = parser:parse()[1]:root()
|
||||||
local injections = {} ---@type table<integer,table>
|
local injections = {} ---@type table<integer,table>
|
||||||
parser:for_each_child(function(child, lang_)
|
for _, child in pairs(parser:children()) do
|
||||||
child:for_each_tree(function(tree)
|
child:for_each_tree(function(tree, ltree)
|
||||||
local r = tree:root()
|
local r = tree:root()
|
||||||
local node = root:named_descendant_for_range(r:range())
|
local node = root:named_descendant_for_range(r:range())
|
||||||
if node then
|
if node then
|
||||||
injections[node:id()] = {
|
injections[node:id()] = {
|
||||||
lang = lang_,
|
lang = ltree:lang(),
|
||||||
root = r,
|
root = r,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end
|
||||||
|
|
||||||
local nodes = traverse(root, 0, parser:lang(), injections, {})
|
local nodes = traverse(root, 0, parser:lang(), injections, {})
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ local decor_ns = api.nvim_create_namespace('ts.playground')
|
|||||||
---@param end_lnum integer
|
---@param end_lnum integer
|
||||||
---@param end_col integer
|
---@param end_col integer
|
||||||
---@return string
|
---@return string
|
||||||
local function get_range_str(lnum, col, end_col, end_lnum)
|
local function get_range_str(lnum, col, end_lnum, end_col)
|
||||||
if lnum == end_lnum then
|
if lnum == end_lnum then
|
||||||
return string.format('[%d:%d - %d]', lnum + 1, col + 1, end_col)
|
return string.format('[%d:%d - %d]', lnum + 1, col + 1, end_col)
|
||||||
end
|
end
|
||||||
|
@@ -458,7 +458,7 @@ local directive_handlers = {
|
|||||||
metadata[id] = {}
|
metadata[id] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local pattern, replacement = pred[3], pred[3]
|
local pattern, replacement = pred[3], pred[4]
|
||||||
assert(type(pattern) == 'string')
|
assert(type(pattern) == 'string')
|
||||||
assert(type(replacement) == 'string')
|
assert(type(replacement) == 'string')
|
||||||
|
|
||||||
|
@@ -26,6 +26,9 @@
|
|||||||
</screenshots>
|
</screenshots>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
|
<release date="2023-10-09" version="0.9.4"/>
|
||||||
|
<release date="2023-09-07" version="0.9.2"/>
|
||||||
|
<release date="2023-05-29" version="0.9.1"/>
|
||||||
<release date="2023-04-07" version="0.9.0"/>
|
<release date="2023-04-07" version="0.9.0"/>
|
||||||
<release date="2023-02-02" version="0.8.3"/>
|
<release date="2023-02-02" version="0.8.3"/>
|
||||||
<release date="2022-12-29" version="0.8.2"/>
|
<release date="2022-12-29" version="0.8.2"/>
|
||||||
|
@@ -245,7 +245,7 @@ func s:StartDebug_term(dict)
|
|||||||
|
|
||||||
" Create a hidden terminal window to communicate with gdb
|
" Create a hidden terminal window to communicate with gdb
|
||||||
let s:comm_job_id = jobstart('tail -f /dev/null;#gdb communication', {
|
let s:comm_job_id = jobstart('tail -f /dev/null;#gdb communication', {
|
||||||
\ 'on_stdout': function('s:CommOutput'),
|
\ 'on_stdout': function('s:JobOutCallback', {'last_line': '', 'real_cb': function('s:CommOutput')}),
|
||||||
\ 'pty': v:true,
|
\ 'pty': v:true,
|
||||||
\ })
|
\ })
|
||||||
" hide terminal buffer
|
" hide terminal buffer
|
||||||
@@ -430,7 +430,7 @@ func s:StartDebug_prompt(dict)
|
|||||||
" call ch_log('executing "' . join(gdb_cmd) . '"')
|
" call ch_log('executing "' . join(gdb_cmd) . '"')
|
||||||
let s:gdbjob = jobstart(gdb_cmd, {
|
let s:gdbjob = jobstart(gdb_cmd, {
|
||||||
\ 'on_exit': function('s:EndPromptDebug'),
|
\ 'on_exit': function('s:EndPromptDebug'),
|
||||||
\ 'on_stdout': function('s:GdbOutCallback'),
|
\ 'on_stdout': function('s:JobOutCallback', {'last_line': '', 'real_cb': function('s:GdbOutCallback')}),
|
||||||
\ })
|
\ })
|
||||||
if s:gdbjob == 0
|
if s:gdbjob == 0
|
||||||
echoerr 'invalid argument (or job table is full) while starting gdb job'
|
echoerr 'invalid argument (or job table is full) while starting gdb job'
|
||||||
@@ -594,6 +594,23 @@ func s:PromptInterrupt()
|
|||||||
endif
|
endif
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Wrapper around job callback that handles partial lines (:h channel-lines).
|
||||||
|
" It should be called from a Dictionary with the following keys:
|
||||||
|
" - last_line: the last (partial) line received
|
||||||
|
" - real_cb: a callback that assumes full lines
|
||||||
|
func s:JobOutCallback(jobid, data, event) dict
|
||||||
|
let eof = (a:data == [''])
|
||||||
|
let msgs = a:data
|
||||||
|
let msgs[0] = self.last_line .. msgs[0]
|
||||||
|
if eof
|
||||||
|
let self.last_line = ''
|
||||||
|
else
|
||||||
|
let self.last_line = msgs[-1]
|
||||||
|
unlet msgs[-1]
|
||||||
|
endif
|
||||||
|
call self.real_cb(a:jobid, msgs, a:event)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" Function called when gdb outputs text.
|
" Function called when gdb outputs text.
|
||||||
func s:GdbOutCallback(job_id, msgs, event)
|
func s:GdbOutCallback(job_id, msgs, event)
|
||||||
"call ch_log('received from gdb: ' . a:text)
|
"call ch_log('received from gdb: ' . a:text)
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
(preproc_else)
|
(preproc_else)
|
||||||
(preproc_ifdef)
|
(preproc_ifdef)
|
||||||
(initializer_list)
|
(initializer_list)
|
||||||
|
(gnu_asm_expression)
|
||||||
] @fold
|
] @fold
|
||||||
|
|
||||||
(compound_statement
|
(compound_statement
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
; Lower priority to prefer @parameter when identifier appears in parameter_declaration.
|
; Lower priority to prefer @parameter when identifier appears in parameter_declaration.
|
||||||
((identifier) @variable (#set! "priority" 95))
|
((identifier) @variable (#set! "priority" 95))
|
||||||
|
(preproc_def (preproc_arg) @variable)
|
||||||
|
|
||||||
[
|
[
|
||||||
"default"
|
"default"
|
||||||
@@ -8,9 +9,14 @@
|
|||||||
"typedef"
|
"typedef"
|
||||||
"union"
|
"union"
|
||||||
"goto"
|
"goto"
|
||||||
|
"asm"
|
||||||
|
"__asm__"
|
||||||
] @keyword
|
] @keyword
|
||||||
|
|
||||||
"sizeof" @keyword.operator
|
[
|
||||||
|
"sizeof"
|
||||||
|
"offsetof"
|
||||||
|
] @keyword.operator
|
||||||
|
|
||||||
"return" @keyword.return
|
"return" @keyword.return
|
||||||
|
|
||||||
@@ -36,6 +42,8 @@
|
|||||||
"#else"
|
"#else"
|
||||||
"#elif"
|
"#elif"
|
||||||
"#endif"
|
"#endif"
|
||||||
|
"#elifdef"
|
||||||
|
"#elifndef"
|
||||||
(preproc_directive)
|
(preproc_directive)
|
||||||
] @preproc
|
] @preproc
|
||||||
|
|
||||||
@@ -43,7 +51,7 @@
|
|||||||
|
|
||||||
"#include" @include
|
"#include" @include
|
||||||
|
|
||||||
[ ";" ":" "," ] @punctuation.delimiter
|
[ ";" ":" "," "::" ] @punctuation.delimiter
|
||||||
|
|
||||||
"..." @punctuation.special
|
"..." @punctuation.special
|
||||||
|
|
||||||
@@ -112,23 +120,31 @@
|
|||||||
(number_literal) @number
|
(number_literal) @number
|
||||||
(char_literal) @character
|
(char_literal) @character
|
||||||
|
|
||||||
[
|
((preproc_arg) @function.macro (#set! "priority" 90))
|
||||||
(preproc_arg)
|
(preproc_defined) @function.macro
|
||||||
(preproc_defined)
|
|
||||||
] @function.macro
|
(((field_expression
|
||||||
|
(field_identifier) @property)) @_parent
|
||||||
|
(#not-has-parent? @_parent template_method function_declarator call_expression))
|
||||||
|
|
||||||
|
(field_designator) @property
|
||||||
|
(((field_identifier) @property)
|
||||||
|
(#has-ancestor? @property field_declaration)
|
||||||
|
(#not-has-ancestor? @property function_declarator))
|
||||||
|
|
||||||
(field_identifier) @property
|
|
||||||
(statement_identifier) @label
|
(statement_identifier) @label
|
||||||
|
|
||||||
[
|
[
|
||||||
(type_identifier)
|
(type_identifier)
|
||||||
(sized_type_specifier)
|
|
||||||
(type_descriptor)
|
(type_descriptor)
|
||||||
] @type
|
] @type
|
||||||
|
|
||||||
(storage_class_specifier) @storageclass
|
(storage_class_specifier) @storageclass
|
||||||
|
|
||||||
(type_qualifier) @type.qualifier
|
[
|
||||||
|
(type_qualifier)
|
||||||
|
(gnu_asm_qualifier)
|
||||||
|
] @type.qualifier
|
||||||
|
|
||||||
(linkage_specification
|
(linkage_specification
|
||||||
"extern" @storageclass)
|
"extern" @storageclass)
|
||||||
@@ -138,8 +154,12 @@
|
|||||||
|
|
||||||
(primitive_type) @type.builtin
|
(primitive_type) @type.builtin
|
||||||
|
|
||||||
|
(sized_type_specifier _ @type.builtin type: _?)
|
||||||
|
|
||||||
((identifier) @constant
|
((identifier) @constant
|
||||||
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
|
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||||
|
(preproc_def (preproc_arg) @constant
|
||||||
|
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||||
(enumerator
|
(enumerator
|
||||||
name: (identifier) @constant)
|
name: (identifier) @constant)
|
||||||
(case_statement
|
(case_statement
|
||||||
@@ -147,6 +167,8 @@
|
|||||||
|
|
||||||
((identifier) @constant.builtin
|
((identifier) @constant.builtin
|
||||||
(#any-of? @constant.builtin "stderr" "stdin" "stdout"))
|
(#any-of? @constant.builtin "stderr" "stdin" "stdout"))
|
||||||
|
(preproc_def (preproc_arg) @constant.builtin
|
||||||
|
(#any-of? @constant.builtin "stderr" "stdin" "stdout"))
|
||||||
|
|
||||||
;; Preproc def / undef
|
;; Preproc def / undef
|
||||||
(preproc_def
|
(preproc_def
|
||||||
@@ -163,6 +185,10 @@
|
|||||||
field: (field_identifier) @function.call))
|
field: (field_identifier) @function.call))
|
||||||
(function_declarator
|
(function_declarator
|
||||||
declarator: (identifier) @function)
|
declarator: (identifier) @function)
|
||||||
|
(function_declarator
|
||||||
|
declarator: (parenthesized_declarator
|
||||||
|
(pointer_declarator
|
||||||
|
declarator: (field_identifier) @function)))
|
||||||
(preproc_function_def
|
(preproc_function_def
|
||||||
name: (identifier) @function.macro)
|
name: (identifier) @function.macro)
|
||||||
|
|
||||||
@@ -175,6 +201,9 @@
|
|||||||
(parameter_declaration
|
(parameter_declaration
|
||||||
declarator: (identifier) @parameter)
|
declarator: (identifier) @parameter)
|
||||||
|
|
||||||
|
(parameter_declaration
|
||||||
|
declarator: (array_declarator) @parameter)
|
||||||
|
|
||||||
(parameter_declaration
|
(parameter_declaration
|
||||||
declarator: (pointer_declarator) @parameter)
|
declarator: (pointer_declarator) @parameter)
|
||||||
|
|
||||||
@@ -182,15 +211,15 @@
|
|||||||
|
|
||||||
[
|
[
|
||||||
"__attribute__"
|
"__attribute__"
|
||||||
|
"__declspec"
|
||||||
|
"__based"
|
||||||
"__cdecl"
|
"__cdecl"
|
||||||
"__clrcall"
|
"__clrcall"
|
||||||
"__stdcall"
|
"__stdcall"
|
||||||
"__fastcall"
|
"__fastcall"
|
||||||
"__thiscall"
|
"__thiscall"
|
||||||
"__vectorcall"
|
"__vectorcall"
|
||||||
"_unaligned"
|
(ms_pointer_modifier)
|
||||||
"__unaligned"
|
|
||||||
"__declspec"
|
|
||||||
(attribute_declaration)
|
(attribute_declaration)
|
||||||
] @attribute
|
] @attribute
|
||||||
|
|
||||||
|
@@ -127,8 +127,14 @@
|
|||||||
|
|
||||||
(identifier) @variable
|
(identifier) @variable
|
||||||
|
|
||||||
|
((identifier) @constant.builtin
|
||||||
|
(#eq? @constant.builtin "_VERSION"))
|
||||||
|
|
||||||
((identifier) @variable.builtin
|
((identifier) @variable.builtin
|
||||||
(#any-of? @variable.builtin "_G" "_VERSION" "debug" "io" "jit" "math" "os" "package" "self" "string" "table" "utf8"))
|
(#eq? @variable.builtin "self"))
|
||||||
|
|
||||||
|
((identifier) @namespace.builtin
|
||||||
|
(#any-of? @namespace.builtin "_G" "debug" "io" "jit" "math" "os" "package" "string" "table" "utf8"))
|
||||||
|
|
||||||
((identifier) @keyword.coroutine
|
((identifier) @keyword.coroutine
|
||||||
(#eq? @keyword.coroutine "coroutine"))
|
(#eq? @keyword.coroutine "coroutine"))
|
||||||
@@ -174,13 +180,40 @@
|
|||||||
|
|
||||||
(parameters (identifier) @parameter)
|
(parameters (identifier) @parameter)
|
||||||
|
|
||||||
(function_call name: (identifier) @function.call)
|
(function_declaration
|
||||||
(function_declaration name: (identifier) @function)
|
name: [
|
||||||
|
(identifier) @function
|
||||||
|
(dot_index_expression
|
||||||
|
field: (identifier) @function)
|
||||||
|
])
|
||||||
|
|
||||||
(function_call name: (dot_index_expression field: (identifier) @function.call))
|
(function_declaration
|
||||||
(function_declaration name: (dot_index_expression field: (identifier) @function))
|
name: (method_index_expression
|
||||||
|
method: (identifier) @method))
|
||||||
|
|
||||||
(method_index_expression method: (identifier) @method.call)
|
(assignment_statement
|
||||||
|
(variable_list .
|
||||||
|
name: [
|
||||||
|
(identifier) @function
|
||||||
|
(dot_index_expression
|
||||||
|
field: (identifier) @function)
|
||||||
|
])
|
||||||
|
(expression_list .
|
||||||
|
value: (function_definition)))
|
||||||
|
|
||||||
|
(table_constructor
|
||||||
|
(field
|
||||||
|
name: (identifier) @function
|
||||||
|
value: (function_definition)))
|
||||||
|
|
||||||
|
(function_call
|
||||||
|
name: [
|
||||||
|
(identifier) @function.call
|
||||||
|
(dot_index_expression
|
||||||
|
field: (identifier) @function.call)
|
||||||
|
(method_index_expression
|
||||||
|
method: (identifier) @method.call)
|
||||||
|
])
|
||||||
|
|
||||||
(function_call
|
(function_call
|
||||||
(identifier) @function.builtin
|
(identifier) @function.builtin
|
||||||
@@ -208,7 +241,9 @@
|
|||||||
|
|
||||||
(number) @number
|
(number) @number
|
||||||
|
|
||||||
(string) @string @spell
|
(string) @string
|
||||||
|
|
||||||
|
(escape_sequence) @string.escape
|
||||||
|
|
||||||
;; Error
|
;; Error
|
||||||
(ERROR) @error
|
(ERROR) @error
|
||||||
|
@@ -13,6 +13,14 @@
|
|||||||
(#set! injection.language "vim")
|
(#set! injection.language "vim")
|
||||||
(#any-of? @_vimcmd_identifier "vim.cmd" "vim.api.nvim_command" "vim.api.nvim_exec2" "vim.api.nvim_cmd"))
|
(#any-of? @_vimcmd_identifier "vim.cmd" "vim.api.nvim_command" "vim.api.nvim_exec2" "vim.api.nvim_cmd"))
|
||||||
|
|
||||||
|
; vim.rcprequest(123, "nvim_exec_lua", "return vim.api.nvim_buf_get_lines(0, 0, -1, false)", false)
|
||||||
|
((function_call
|
||||||
|
name: (_) @_vimcmd_identifier
|
||||||
|
arguments: (arguments . (_) . (string content: _ @_method) . (string content: _ @injection.content)))
|
||||||
|
(#set! injection.language "lua")
|
||||||
|
(#any-of? @_vimcmd_identifier "vim.rpcrequest" "vim.rpcnotify")
|
||||||
|
(#eq? @_method "nvim_exec_lua"))
|
||||||
|
|
||||||
((function_call
|
((function_call
|
||||||
name: (_) @_vimcmd_identifier
|
name: (_) @_vimcmd_identifier
|
||||||
arguments: (arguments (string content: _ @injection.content) .))
|
arguments: (arguments (string content: _ @injection.content) .))
|
||||||
@@ -20,7 +28,7 @@
|
|||||||
(#any-of? @_vimcmd_identifier "vim.treesitter.query.set" "vim.treesitter.query.parse"))
|
(#any-of? @_vimcmd_identifier "vim.treesitter.query.set" "vim.treesitter.query.parse"))
|
||||||
|
|
||||||
;; highlight string as query if starts with `;; query`
|
;; highlight string as query if starts with `;; query`
|
||||||
((string ("string_content") @injection.content)
|
(string content: _ @injection.content
|
||||||
(#set! injection.language "query")
|
(#set! injection.language "query")
|
||||||
(#lua-match? @injection.content "^%s*;+%s?query"))
|
(#lua-match? @injection.content "^%s*;+%s?query"))
|
||||||
|
|
||||||
|
@@ -27,8 +27,8 @@
|
|||||||
((parameters (identifier) @number)
|
((parameters (identifier) @number)
|
||||||
(#match? @number "^[-+]?[0-9]+(.[0-9]+)?$"))
|
(#match? @number "^[-+]?[0-9]+(.[0-9]+)?$"))
|
||||||
|
|
||||||
((program . (comment) @include)
|
((program . (comment)* . (comment) @include)
|
||||||
(#match? @include "^;\ +inherits\ *:"))
|
(#lua-match? @include "^;+ *inherits *:"))
|
||||||
|
|
||||||
((program . (comment) @preproc)
|
((program . (comment)* . (comment) @preproc)
|
||||||
(#match? @preproc "^; +extends"))
|
(#lua-match? @preproc "^;+ *extends"))
|
||||||
|
@@ -275,7 +275,7 @@
|
|||||||
|
|
||||||
; Options
|
; Options
|
||||||
((set_value) @number
|
((set_value) @number
|
||||||
(#match? @number "^[0-9]+(\.[0-9]+)?$"))
|
(#lua-match? @number "^[%d]+(%.[%d]+)?$"))
|
||||||
|
|
||||||
(inv_option "!" @operator)
|
(inv_option "!" @operator)
|
||||||
(set_item "?" @operator)
|
(set_item "?" @operator)
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
(h1) @text.title
|
(h1) @text.title.1
|
||||||
(h2) @text.title
|
(h2) @text.title.2
|
||||||
(h3) @text.title
|
(h3) @text.title.3
|
||||||
(column_heading) @text.title
|
(column_heading) @text.title.4
|
||||||
(column_heading
|
(column_heading
|
||||||
"~" @conceal (#set! conceal ""))
|
"~" @conceal (#set! conceal ""))
|
||||||
(tag
|
(tag
|
||||||
|
@@ -1,15 +1,18 @@
|
|||||||
|
" Nvim syntax file
|
||||||
|
" Language: EditorConfig
|
||||||
|
" Last Change: 2023-07-20
|
||||||
|
"
|
||||||
|
" This file is intentionally _not_ copied from Vim.
|
||||||
|
|
||||||
runtime! syntax/dosini.vim
|
runtime! syntax/dosini.vim
|
||||||
unlet! b:current_syntax
|
unlet! b:current_syntax
|
||||||
|
|
||||||
syntax match editorconfigUnknownProperty "^\s*\zs\w\+\ze\s*="
|
syntax match editorconfigUnknownProperty "^\s*\zs[a-zA-Z0-9_-]\+\ze\s*="
|
||||||
syntax keyword editorconfigProperty root
|
syntax keyword editorconfigProperty root
|
||||||
|
|
||||||
lua<<
|
lua<<
|
||||||
local props = {}
|
local props = vim.tbl_keys(require('editorconfig').properties)
|
||||||
for k in pairs(require('editorconfig').properties) do
|
vim.cmd.syntax { 'keyword', 'editorconfigProperty', unpack(props) }
|
||||||
props[#props + 1] = k
|
|
||||||
end
|
|
||||||
vim.cmd(string.format('syntax keyword editorconfigProperty %s', table.concat(props, ' ')))
|
|
||||||
.
|
.
|
||||||
|
|
||||||
hi def link editorconfigProperty dosiniLabel
|
hi def link editorconfigProperty dosiniLabel
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
Neovim is a very powerful editor that has many commands, too many to explain in
|
Neovim is a very powerful editor that has many commands, too many to explain in
|
||||||
a tutorial such as this. This tutorial is designed to describe enough of the
|
a tutorial such as this. This tutorial is designed to describe enough of the
|
||||||
commands that you will be able to easily use Neovim as an all-purpose editor.
|
commands that you will be able to easily use Neovim as an all-purpose editor.
|
||||||
|
|
||||||
It is IMPORTANT to remember that this tutorial is set up to teach by use. That
|
It is IMPORTANT to remember that this tutorial is set up to teach by use. That
|
||||||
means that you need to do the exercises to learn them properly. If you only
|
means that you need to do the exercises to learn them properly. If you only
|
||||||
read the text, you will soon forget what is most important!
|
read the text, you will soon forget what is most important!
|
||||||
@@ -19,17 +20,16 @@ pressing [<Esc>](<Esc>) and then [u](u) will undo the latest change.
|
|||||||
This tutorial is interactive, and there are a few things you should know.
|
This tutorial is interactive, and there are a few things you should know.
|
||||||
- Type [<Enter>](<Enter>) on links [like this](holy-grail ) to open the linked help section.
|
- Type [<Enter>](<Enter>) on links [like this](holy-grail ) to open the linked help section.
|
||||||
- Or simply type [K](K) on any word to find its documentation!
|
- Or simply type [K](K) on any word to find its documentation!
|
||||||
- You can close this help window with `:q`{vim}
|
- You can close this help window with `:q`{vim} `<Enter>`{normal}
|
||||||
- Sometimes you will be required to modify text like
|
|
||||||
|
|
||||||
this here
|
|
||||||
|
|
||||||
|
When there is a ✗ sign at the left, you will be required to modify text.
|
||||||
Once you have done the changes correctly, the ✗ sign at the left will change
|
Once you have done the changes correctly, the ✗ sign at the left will change
|
||||||
to ✓. I imagine you can already see how neat Neovim can be.
|
to ✓. I imagine you can already see how neat Neovim can be.
|
||||||
|
|
||||||
Other times, you'll be prompted to run a command (I'll explain this later):
|
Other times, you'll be prompted to run a command (I'll explain this later):
|
||||||
~~~ cmd
|
|
||||||
:help <Enter>
|
`:help`{vim} `<Enter>`{normal}
|
||||||
~~~
|
|
||||||
or press a sequence of keys
|
or press a sequence of keys
|
||||||
~~~ normal
|
~~~ normal
|
||||||
<Esc>0f<Space>d3wP$P
|
<Esc>0f<Space>d3wP$P
|
||||||
@@ -70,19 +70,19 @@ NOTE: The cursor keys should also work. But using hjkl you will be able to
|
|||||||
|
|
||||||
2. Type:
|
2. Type:
|
||||||
|
|
||||||
`:q!`{vim} `<Enter>`{normal}.
|
`:q!`{vim} `<Enter>`{normal}
|
||||||
|
|
||||||
This quits the editor, DISCARDING any changes you have made.
|
This quits the editor, DISCARDING any changes you have made.
|
||||||
|
|
||||||
3. Open Neovim and get back here by executing the command that got you into
|
3. Open Neovim and get back here by executing the command that got you into
|
||||||
this tutorial. That might be:
|
this tutorial. That might be:
|
||||||
|
|
||||||
:Tutor <Enter>
|
`:Tutor`{vim} `<Enter>`{normal}
|
||||||
|
|
||||||
4. If you have these steps memorized and are confident, execute steps
|
4. If you have these steps memorized and are confident, execute steps
|
||||||
1 through 3 to exit and re-enter the editor.
|
1 through 3 to exit and re-enter the editor.
|
||||||
|
|
||||||
NOTE: [:q!](:q) <Enter> discards any changes you made. In a few lessons you
|
NOTE: [:q!](:q) `<Enter>`{normal} discards any changes you made. In a few lessons you
|
||||||
will learn how to save the changes to a file.
|
will learn how to save the changes to a file.
|
||||||
|
|
||||||
5. Move the cursor down to Lesson 1.3.
|
5. Move the cursor down to Lesson 1.3.
|
||||||
@@ -438,7 +438,7 @@ Notice that [c](c)e deletes the word and places you in Insert mode.
|
|||||||
5. Type `c$`{normal} and type the rest of the line like the second and press `<Esc>`{normal}.
|
5. Type `c$`{normal} and type the rest of the line like the second and press `<Esc>`{normal}.
|
||||||
|
|
||||||
The end of this line needs some help to make it like the second.
|
The end of this line needs some help to make it like the second.
|
||||||
The end of this line needs to be corrected using the `c$`{normal} command.
|
The end of this line needs to be corrected using the c$ command.
|
||||||
|
|
||||||
NOTE: You can use the Backspace key to correct mistakes while typing.
|
NOTE: You can use the Backspace key to correct mistakes while typing.
|
||||||
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"expect": {
|
"expect": {
|
||||||
"25": -1,
|
|
||||||
"103": "The cow jumped over the moon.",
|
"103": "The cow jumped over the moon.",
|
||||||
"125": "There is some text missing from this line.",
|
"125": "There is some text missing from this line.",
|
||||||
"126": "There is some text missing from this line.",
|
"126": "There is some text missing from this line.",
|
||||||
@@ -28,8 +27,8 @@
|
|||||||
"399": "When this line was typed in, someone pressed some wrong keys!",
|
"399": "When this line was typed in, someone pressed some wrong keys!",
|
||||||
"419": "This line has a few words that need changing using the change operator.",
|
"419": "This line has a few words that need changing using the change operator.",
|
||||||
"420": "This line has a few words that need changing using the change operator.",
|
"420": "This line has a few words that need changing using the change operator.",
|
||||||
"440": "The end of this line needs to be corrected using the `c$` command.",
|
"440": "The end of this line needs to be corrected using the c$ command.",
|
||||||
"441": "The end of this line needs to be corrected using the `c$` command.",
|
"441": "The end of this line needs to be corrected using the c$ command.",
|
||||||
"504": -1,
|
"504": -1,
|
||||||
"523": -1,
|
"523": -1,
|
||||||
"546": "Usually the best time to see the flowers is in the spring.",
|
"546": "Usually the best time to see the flowers is in the spring.",
|
||||||
|
@@ -217,7 +217,6 @@ CONFIG = {
|
|||||||
'util.lua',
|
'util.lua',
|
||||||
'log.lua',
|
'log.lua',
|
||||||
'rpc.lua',
|
'rpc.lua',
|
||||||
'sync.lua',
|
|
||||||
'protocol.lua',
|
'protocol.lua',
|
||||||
],
|
],
|
||||||
'files': [
|
'files': [
|
||||||
|
@@ -26,7 +26,7 @@ APP_DIR="$APP.AppDir"
|
|||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
# Build and install nvim into the AppImage
|
# Build and install nvim into the AppImage
|
||||||
make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_EXTRA_FLAGS="-DCI_BUILD=OFF -DCMAKE_INSTALL_PREFIX=${APP_DIR}/usr -DCMAKE_INSTALL_MANDIR=man"
|
make CMAKE_BUILD_TYPE="${NVIM_BUILD_TYPE}" CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=${APP_DIR}/usr -DCMAKE_INSTALL_MANDIR=man"
|
||||||
make install
|
make install
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
@@ -233,7 +233,7 @@ static mpack_uint32_t lmpack_objlen(lua_State *L, int *is_array)
|
|||||||
while (lua_next(L, -2)) {
|
while (lua_next(L, -2)) {
|
||||||
lua_pop(L, 1); /* pop value */
|
lua_pop(L, 1); /* pop value */
|
||||||
isarr = isarr
|
isarr = isarr
|
||||||
&& lua_isnumber(L, -1) /* lua number */
|
&& lua_type(L, -1) == LUA_TNUMBER /* lua number */
|
||||||
&& (n = lua_tonumber(L, -1)) > 0 /* greater than 0 */
|
&& (n = lua_tonumber(L, -1)) > 0 /* greater than 0 */
|
||||||
&& (size_t)n == n; /* and integer */
|
&& (size_t)n == n; /* and integer */
|
||||||
max = isarr && (size_t)n > max ? (size_t)n : max;
|
max = isarr && (size_t)n > max ? (size_t)n : max;
|
||||||
|
@@ -146,11 +146,7 @@ if(HAS_DIAG_COLOR_FLAG)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if($ENV{CI})
|
|
||||||
option(CI_BUILD "CI, extra flags will be set" ON)
|
|
||||||
else()
|
|
||||||
option(CI_BUILD "CI, extra flags will be set" OFF)
|
option(CI_BUILD "CI, extra flags will be set" OFF)
|
||||||
endif()
|
|
||||||
if(CI_BUILD)
|
if(CI_BUILD)
|
||||||
message(STATUS "CI build enabled")
|
message(STATUS "CI build enabled")
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
@@ -217,6 +213,11 @@ if(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
target_link_libraries(nvim PRIVATE "-framework CoreServices")
|
target_link_libraries(nvim PRIVATE "-framework CoreServices")
|
||||||
|
|
||||||
|
# Actually export symbols - symbols may not be visible even though
|
||||||
|
# ENABLE_EXPORTS is set to true. See
|
||||||
|
# https://github.com/neovim/neovim/issues/25295
|
||||||
|
set_target_properties(nvim PROPERTIES LINK_FLAGS "-Wl,-export_dynamic")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
@@ -275,11 +276,12 @@ set(LUA_LOADER_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/loader.lua)
|
|||||||
set(LUA_INSPECT_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/inspect.lua)
|
set(LUA_INSPECT_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/inspect.lua)
|
||||||
set(LUA_FS_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/fs.lua)
|
set(LUA_FS_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/fs.lua)
|
||||||
set(LUA_F_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/F.lua)
|
set(LUA_F_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/F.lua)
|
||||||
set(LUA_META_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_meta.lua)
|
set(LUA_OPTIONS_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_options.lua)
|
||||||
set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lua)
|
set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lua)
|
||||||
set(LUA_INIT_PACKAGES_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_init_packages.lua)
|
set(LUA_INIT_PACKAGES_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/_init_packages.lua)
|
||||||
set(LUA_KEYMAP_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/keymap.lua)
|
set(LUA_KEYMAP_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/keymap.lua)
|
||||||
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
|
set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
|
||||||
|
set(LUAJIT_RUNTIME_DIR ${DEPS_PREFIX}/share/luajit-2.1/jit)
|
||||||
|
|
||||||
glob_wrapper(UNICODE_FILES ${UNICODE_DIR}/*.txt)
|
glob_wrapper(UNICODE_FILES ${UNICODE_DIR}/*.txt)
|
||||||
glob_wrapper(API_HEADERS api/*.h)
|
glob_wrapper(API_HEADERS api/*.h)
|
||||||
@@ -391,11 +393,14 @@ foreach(gen_cdef DO_NOT_DEFINE_EMPTY_ATTRIBUTES ${prop})
|
|||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
get_target_property(prop main_lib INTERFACE_INCLUDE_DIRECTORIES)
|
get_directory_property(targets BUILDSYSTEM_TARGETS)
|
||||||
|
foreach(target ${targets})
|
||||||
|
get_target_property(prop ${target} INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
foreach(gen_include ${prop})
|
foreach(gen_include ${prop})
|
||||||
list(APPEND gen_cflags "-I${gen_include}")
|
list(APPEND gen_cflags "-I${gen_include}")
|
||||||
endforeach()
|
endforeach()
|
||||||
list(APPEND gen_cflags "-I${DEPS_PREFIX}/include")
|
endforeach()
|
||||||
|
|
||||||
if(APPLE AND CMAKE_OSX_SYSROOT)
|
if(APPLE AND CMAKE_OSX_SYSROOT)
|
||||||
list(APPEND gen_cflags "-isysroot")
|
list(APPEND gen_cflags "-isysroot")
|
||||||
list(APPEND gen_cflags "${CMAKE_OSX_SYSROOT}")
|
list(APPEND gen_cflags "${CMAKE_OSX_SYSROOT}")
|
||||||
@@ -511,7 +516,7 @@ add_custom_command(
|
|||||||
${LUA_SHARED_MODULE_SOURCE} "vim.shared"
|
${LUA_SHARED_MODULE_SOURCE} "vim.shared"
|
||||||
${LUA_LOADER_MODULE_SOURCE} "vim.loader"
|
${LUA_LOADER_MODULE_SOURCE} "vim.loader"
|
||||||
${LUA_F_MODULE_SOURCE} "vim.F"
|
${LUA_F_MODULE_SOURCE} "vim.F"
|
||||||
${LUA_META_MODULE_SOURCE} "vim._meta"
|
${LUA_OPTIONS_MODULE_SOURCE} "vim._options"
|
||||||
${LUA_FILETYPE_MODULE_SOURCE} "vim.filetype"
|
${LUA_FILETYPE_MODULE_SOURCE} "vim.filetype"
|
||||||
${LUA_KEYMAP_MODULE_SOURCE} "vim.keymap"
|
${LUA_KEYMAP_MODULE_SOURCE} "vim.keymap"
|
||||||
DEPENDS
|
DEPENDS
|
||||||
@@ -522,7 +527,7 @@ add_custom_command(
|
|||||||
${LUA_LOADER_MODULE_SOURCE}
|
${LUA_LOADER_MODULE_SOURCE}
|
||||||
${LUA_INSPECT_MODULE_SOURCE}
|
${LUA_INSPECT_MODULE_SOURCE}
|
||||||
${LUA_F_MODULE_SOURCE}
|
${LUA_F_MODULE_SOURCE}
|
||||||
${LUA_META_MODULE_SOURCE}
|
${LUA_OPTIONS_MODULE_SOURCE}
|
||||||
${LUA_FILETYPE_MODULE_SOURCE}
|
${LUA_FILETYPE_MODULE_SOURCE}
|
||||||
${LUA_LOAD_PACKAGE_MODULE_SOURCE}
|
${LUA_LOAD_PACKAGE_MODULE_SOURCE}
|
||||||
${LUA_KEYMAP_MODULE_SOURCE}
|
${LUA_KEYMAP_MODULE_SOURCE}
|
||||||
@@ -779,6 +784,15 @@ install(DIRECTORY ${BINARY_LIB_DIR}
|
|||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/nvim/
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/nvim/
|
||||||
USE_SOURCE_PERMISSIONS)
|
USE_SOURCE_PERMISSIONS)
|
||||||
|
|
||||||
|
if(NOT PREFER_LUA)
|
||||||
|
# install luajit runtime files if bundled
|
||||||
|
if(EXISTS ${LUAJIT_RUNTIME_DIR})
|
||||||
|
install(DIRECTORY ${LUAJIT_RUNTIME_DIR}
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/nvim/runtime/lua
|
||||||
|
USE_SOURCE_PERMISSIONS)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(libnvim STATIC EXCLUDE_FROM_ALL)
|
add_library(libnvim STATIC EXCLUDE_FROM_ALL)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set(LIBNVIM_NAME libnvim)
|
set(LIBNVIM_NAME libnvim)
|
||||||
|
@@ -209,15 +209,11 @@ To debug the main process, you can debug the nvim binary with the `--headless`
|
|||||||
flag which does not launch the TUI and will allow you to set breakpoints in code
|
flag which does not launch the TUI and will allow you to set breakpoints in code
|
||||||
not related to TUI rendering like so:
|
not related to TUI rendering like so:
|
||||||
|
|
||||||
```
|
|
||||||
lldb -- ./build/bin/nvim --headless --listen ~/.cache/nvim/debug-server.pipe
|
lldb -- ./build/bin/nvim --headless --listen ~/.cache/nvim/debug-server.pipe
|
||||||
```
|
|
||||||
|
|
||||||
You can then attach to the headless process to interact with the editor like so:
|
You can then attach to the headless process to interact with the editor like so:
|
||||||
|
|
||||||
```
|
|
||||||
./build/bin/nvim --remote-ui --server ~/.cache/nvim/debug-server.pipe
|
./build/bin/nvim --remote-ui --server ~/.cache/nvim/debug-server.pipe
|
||||||
```
|
|
||||||
|
|
||||||
Conversely for debugging TUI rendering, you can start a headless process and
|
Conversely for debugging TUI rendering, you can start a headless process and
|
||||||
debug the remote-ui process multiple times without losing editor state.
|
debug the remote-ui process multiple times without losing editor state.
|
||||||
|
@@ -33,13 +33,11 @@
|
|||||||
// Copy string or array of strings into an empty array.
|
// Copy string or array of strings into an empty array.
|
||||||
// Get the event number, unless it is an error. Then goto `goto_name`.
|
// Get the event number, unless it is an error. Then goto `goto_name`.
|
||||||
#define GET_ONE_EVENT(event_nr, event_str, goto_name) \
|
#define GET_ONE_EVENT(event_nr, event_str, goto_name) \
|
||||||
char *__next_ev; \
|
|
||||||
event_T event_nr = \
|
event_T event_nr = \
|
||||||
event_name2nr(event_str.data.string.data, &__next_ev); \
|
event_name2nr_str(event_str.data.string); \
|
||||||
if (event_nr >= NUM_EVENTS) { \
|
VALIDATE_S((event_nr < NUM_EVENTS), "event", event_str.data.string.data, { \
|
||||||
api_set_error(err, kErrorTypeValidation, "unexpected event"); \
|
|
||||||
goto goto_name; \
|
goto goto_name; \
|
||||||
}
|
});
|
||||||
|
|
||||||
// ID for associating autocmds created via nvim_create_autocmd
|
// ID for associating autocmds created via nvim_create_autocmd
|
||||||
// Used to delete autocmds from nvim_del_autocmd
|
// Used to delete autocmds from nvim_del_autocmd
|
||||||
@@ -114,7 +112,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err)
|
|||||||
break;
|
break;
|
||||||
case kObjectTypeInteger:
|
case kObjectTypeInteger:
|
||||||
group = (int)opts->group.data.integer;
|
group = (int)opts->group.data.integer;
|
||||||
char *name = augroup_name(group);
|
char *name = group == 0 ? NULL : augroup_name(group);
|
||||||
VALIDATE_INT(augroup_exists(name), "group", opts->group.data.integer, {
|
VALIDATE_INT(augroup_exists(name), "group", opts->group.data.integer, {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
});
|
});
|
||||||
@@ -608,7 +606,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err)
|
|||||||
FOR_ALL_AUEVENTS(event) {
|
FOR_ALL_AUEVENTS(event) {
|
||||||
FOREACH_ITEM(patterns, pat_object, {
|
FOREACH_ITEM(patterns, pat_object, {
|
||||||
char *pat = pat_object.data.string.data;
|
char *pat = pat_object.data.string.data;
|
||||||
if (!clear_autocmd(event, (char *)pat, au_group, err)) {
|
if (!clear_autocmd(event, pat, au_group, err)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -619,7 +617,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err)
|
|||||||
|
|
||||||
FOREACH_ITEM(patterns, pat_object, {
|
FOREACH_ITEM(patterns, pat_object, {
|
||||||
char *pat = pat_object.data.string.data;
|
char *pat = pat_object.data.string.data;
|
||||||
if (!clear_autocmd(event_nr, (char *)pat, au_group, err)) {
|
if (!clear_autocmd(event_nr, pat, au_group, err)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -684,7 +682,7 @@ void nvim_del_augroup_by_id(Integer id, Error *err)
|
|||||||
FUNC_API_SINCE(9)
|
FUNC_API_SINCE(9)
|
||||||
{
|
{
|
||||||
TRY_WRAP(err, {
|
TRY_WRAP(err, {
|
||||||
char *name = augroup_name((int)id);
|
char *name = id == 0 ? NULL : augroup_name((int)id);
|
||||||
augroup_del(name, false);
|
augroup_del(name, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -746,7 +744,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
|
|||||||
break;
|
break;
|
||||||
case kObjectTypeInteger:
|
case kObjectTypeInteger:
|
||||||
au_group = (int)opts->group.data.integer;
|
au_group = (int)opts->group.data.integer;
|
||||||
char *name = augroup_name(au_group);
|
char *name = au_group == 0 ? NULL : augroup_name(au_group);
|
||||||
VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, {
|
VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
});
|
});
|
||||||
@@ -840,7 +838,7 @@ static int get_augroup_from_object(Object group, Error *err)
|
|||||||
return au_group;
|
return au_group;
|
||||||
case kObjectTypeInteger:
|
case kObjectTypeInteger:
|
||||||
au_group = (int)group.data.integer;
|
au_group = (int)group.data.integer;
|
||||||
char *name = augroup_name(au_group);
|
char *name = au_group == 0 ? NULL : augroup_name(au_group);
|
||||||
VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, {
|
VALIDATE_INT(augroup_exists(name), "group", (int64_t)au_group, {
|
||||||
return AUGROUP_ERROR;
|
return AUGROUP_ERROR;
|
||||||
});
|
});
|
||||||
|
@@ -392,6 +392,12 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
|
|||||||
VALIDATE(!is_cmd_ni(ea.cmdidx), "Command not implemented: %s", cmdname, {
|
VALIDATE(!is_cmd_ni(ea.cmdidx), "Command not implemented: %s", cmdname, {
|
||||||
goto end;
|
goto end;
|
||||||
});
|
});
|
||||||
|
const char *fullname = IS_USER_CMDIDX(ea.cmdidx)
|
||||||
|
? get_user_command_name(ea.useridx, ea.cmdidx)
|
||||||
|
: get_command_name(NULL, ea.cmdidx);
|
||||||
|
VALIDATE(strncmp(fullname, cmdname, strlen(cmdname)) == 0, "Invalid command: \"%s\"", cmdname, {
|
||||||
|
goto end;
|
||||||
|
});
|
||||||
|
|
||||||
// Get the command flags so that we can know what type of arguments the command uses.
|
// Get the command flags so that we can know what type of arguments the command uses.
|
||||||
// Not required for a user command since `find_ex_command` already deals with it in that case.
|
// Not required for a user command since `find_ex_command` already deals with it in that case.
|
||||||
|
@@ -208,7 +208,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
|
|||||||
|
|
||||||
// uncrustify:on
|
// uncrustify:on
|
||||||
|
|
||||||
for (int j = 0; hls[j].name && hls[j].val; j++) {
|
for (int j = 0; hls[j].name; j++) {
|
||||||
if (hls[j].val) {
|
if (hls[j].val) {
|
||||||
PUT(dict, hls[j].name, hl_group_name(hls[j].val, hl_name));
|
PUT(dict, hls[j].name, hl_group_name(hls[j].val, hl_name));
|
||||||
}
|
}
|
||||||
|
@@ -49,7 +49,7 @@ typedef struct {
|
|||||||
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
|
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
|
||||||
do { \
|
do { \
|
||||||
const size_t len_ = (size_t)(len); \
|
const size_t len_ = (size_t)(len); \
|
||||||
const char *const str_ = (const char *)(str); \
|
const char *const str_ = (str); \
|
||||||
assert(len_ == 0 || str_ != NULL); \
|
assert(len_ == 0 || str_ != NULL); \
|
||||||
kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
|
kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@@ -73,6 +73,11 @@ static void mpack_uint(char **buf, uint32_t val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mpack_bool(char **buf, bool val)
|
||||||
|
{
|
||||||
|
mpack_w(buf, 0xc2 | val);
|
||||||
|
}
|
||||||
|
|
||||||
static void mpack_array(char **buf, uint32_t len)
|
static void mpack_array(char **buf, uint32_t len)
|
||||||
{
|
{
|
||||||
if (len < 0x10) {
|
if (len < 0x10) {
|
||||||
@@ -210,6 +215,8 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
|
|||||||
|
|
||||||
pmap_put(uint64_t)(&connected_uis, channel_id, ui);
|
pmap_put(uint64_t)(&connected_uis, channel_id, ui);
|
||||||
ui_attach_impl(ui, channel_id);
|
ui_attach_impl(ui, channel_id);
|
||||||
|
|
||||||
|
may_trigger_vim_suspend_resume(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @deprecated
|
/// @deprecated
|
||||||
@@ -232,6 +239,10 @@ void nvim_ui_set_focus(uint64_t channel_id, Boolean gained, Error *error)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gained) {
|
||||||
|
may_trigger_vim_suspend_resume(false);
|
||||||
|
}
|
||||||
|
|
||||||
do_autocmd_focusgained((bool)gained);
|
do_autocmd_focusgained((bool)gained);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,7 +819,7 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
|||||||
data->ncalls++;
|
data->ncalls++;
|
||||||
|
|
||||||
char **buf = &data->buf_wptr;
|
char **buf = &data->buf_wptr;
|
||||||
mpack_array(buf, 4);
|
mpack_array(buf, 5);
|
||||||
mpack_uint(buf, (uint32_t)grid);
|
mpack_uint(buf, (uint32_t)grid);
|
||||||
mpack_uint(buf, (uint32_t)row);
|
mpack_uint(buf, (uint32_t)row);
|
||||||
mpack_uint(buf, (uint32_t)startcol);
|
mpack_uint(buf, (uint32_t)startcol);
|
||||||
@@ -818,21 +829,25 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
|||||||
size_t ncells = (size_t)(endcol - startcol);
|
size_t ncells = (size_t)(endcol - startcol);
|
||||||
int last_hl = -1;
|
int last_hl = -1;
|
||||||
uint32_t nelem = 0;
|
uint32_t nelem = 0;
|
||||||
|
bool was_space = false;
|
||||||
for (size_t i = 0; i < ncells; i++) {
|
for (size_t i = 0; i < ncells; i++) {
|
||||||
repeat++;
|
repeat++;
|
||||||
if (i == ncells - 1 || attrs[i] != attrs[i + 1]
|
if (i == ncells - 1 || attrs[i] != attrs[i + 1]
|
||||||
|| strcmp(chunk[i], chunk[i + 1]) != 0) {
|
|| strcmp(chunk[i], chunk[i + 1]) != 0) {
|
||||||
if (UI_BUF_SIZE - BUF_POS(data) < 2 * (1 + 2 + sizeof(schar_T) + 5 + 5)) {
|
if (UI_BUF_SIZE - BUF_POS(data) < 2 * (1 + 2 + sizeof(schar_T) + 5 + 5) + 1) {
|
||||||
// close to overflowing the redraw buffer. finish this event,
|
// close to overflowing the redraw buffer. finish this event,
|
||||||
// flush, and start a new "grid_line" event at the current position.
|
// flush, and start a new "grid_line" event at the current position.
|
||||||
// For simplicity leave place for the final "clear" element
|
// For simplicity leave place for the final "clear" element
|
||||||
// as well, hence the factor of 2 in the check.
|
// as well, hence the factor of 2 in the check.
|
||||||
mpack_w2(&lenpos, nelem);
|
mpack_w2(&lenpos, nelem);
|
||||||
|
|
||||||
|
// We only ever set the wrap field on the final "grid_line" event for the line.
|
||||||
|
mpack_bool(buf, false);
|
||||||
remote_ui_flush_buf(ui);
|
remote_ui_flush_buf(ui);
|
||||||
|
|
||||||
prepare_call(ui, "grid_line");
|
prepare_call(ui, "grid_line");
|
||||||
data->ncalls++;
|
data->ncalls++;
|
||||||
mpack_array(buf, 4);
|
mpack_array(buf, 5);
|
||||||
mpack_uint(buf, (uint32_t)grid);
|
mpack_uint(buf, (uint32_t)grid);
|
||||||
mpack_uint(buf, (uint32_t)row);
|
mpack_uint(buf, (uint32_t)row);
|
||||||
mpack_uint(buf, (uint32_t)startcol + (uint32_t)i - repeat + 1);
|
mpack_uint(buf, (uint32_t)startcol + (uint32_t)i - repeat + 1);
|
||||||
@@ -843,7 +858,7 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
|||||||
uint32_t csize = (repeat > 1) ? 3 : ((attrs[i] != last_hl) ? 2 : 1);
|
uint32_t csize = (repeat > 1) ? 3 : ((attrs[i] != last_hl) ? 2 : 1);
|
||||||
nelem++;
|
nelem++;
|
||||||
mpack_array(buf, csize);
|
mpack_array(buf, csize);
|
||||||
mpack_str(buf, (const char *)chunk[i]);
|
mpack_str(buf, chunk[i]);
|
||||||
if (csize >= 2) {
|
if (csize >= 2) {
|
||||||
mpack_uint(buf, (uint32_t)attrs[i]);
|
mpack_uint(buf, (uint32_t)attrs[i]);
|
||||||
if (csize >= 3) {
|
if (csize >= 3) {
|
||||||
@@ -853,9 +868,12 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
|||||||
data->ncells_pending += MIN(repeat, 2);
|
data->ncells_pending += MIN(repeat, 2);
|
||||||
last_hl = attrs[i];
|
last_hl = attrs[i];
|
||||||
repeat = 0;
|
repeat = 0;
|
||||||
|
was_space = strequal(chunk[i], " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (endcol < clearcol) {
|
// If the last chunk was all spaces, add a clearing chunk even if there are
|
||||||
|
// no more cells to clear, so there is no ambiguity about what to clear.
|
||||||
|
if (endcol < clearcol || was_space) {
|
||||||
nelem++;
|
nelem++;
|
||||||
data->ncells_pending += 1;
|
data->ncells_pending += 1;
|
||||||
mpack_array(buf, 3);
|
mpack_array(buf, 3);
|
||||||
@@ -864,16 +882,17 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
|
|||||||
mpack_uint(buf, (uint32_t)(clearcol - endcol));
|
mpack_uint(buf, (uint32_t)(clearcol - endcol));
|
||||||
}
|
}
|
||||||
mpack_w2(&lenpos, nelem);
|
mpack_w2(&lenpos, nelem);
|
||||||
|
mpack_bool(buf, flags & kLineFlagWrap);
|
||||||
|
|
||||||
if (data->ncells_pending > 500) {
|
if (data->ncells_pending > 500) {
|
||||||
// pass of cells to UI to let it start processing them
|
// pass off cells to UI to let it start processing them
|
||||||
remote_ui_flush_buf(ui);
|
remote_ui_flush_buf(ui);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < endcol - startcol; i++) {
|
for (int i = 0; i < endcol - startcol; i++) {
|
||||||
remote_ui_cursor_goto(ui, row, startcol + i);
|
remote_ui_cursor_goto(ui, row, startcol + i);
|
||||||
remote_ui_highlight_set(ui, attrs[i]);
|
remote_ui_highlight_set(ui, attrs[i]);
|
||||||
remote_ui_put(ui, (const char *)chunk[i]);
|
remote_ui_put(ui, chunk[i]);
|
||||||
if (utf_ambiguous_width(utf_ptr2char((char *)chunk[i]))) {
|
if (utf_ambiguous_width(utf_ptr2char((char *)chunk[i]))) {
|
||||||
data->client_col = -1; // force cursor update
|
data->client_col = -1; // force cursor update
|
||||||
}
|
}
|
||||||
|
@@ -82,7 +82,7 @@ void grid_clear(Integer grid)
|
|||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
|
||||||
void grid_cursor_goto(Integer grid, Integer row, Integer col)
|
void grid_cursor_goto(Integer grid, Integer row, Integer col)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_COMPOSITOR_IMPL;
|
||||||
void grid_line(Integer grid, Integer row, Integer col_start, Array data)
|
void grid_line(Integer grid, Integer row, Integer col_start, Array data, Boolean wrap)
|
||||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY FUNC_API_CLIENT_IMPL;
|
FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY FUNC_API_CLIENT_IMPL;
|
||||||
void grid_scroll(Integer grid, Integer top, Integer bot, Integer left, Integer right, Integer rows,
|
void grid_scroll(Integer grid, Integer top, Integer bot, Integer left, Integer right, Integer rows,
|
||||||
Integer cols)
|
Integer cols)
|
||||||
|
@@ -305,6 +305,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
|
|||||||
Integer nvim_input(String keys)
|
Integer nvim_input(String keys)
|
||||||
FUNC_API_SINCE(1) FUNC_API_FAST
|
FUNC_API_SINCE(1) FUNC_API_FAST
|
||||||
{
|
{
|
||||||
|
may_trigger_vim_suspend_resume(false);
|
||||||
return (Integer)input_enqueue(keys);
|
return (Integer)input_enqueue(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +335,8 @@ void nvim_input_mouse(String button, String action, String modifier, Integer gri
|
|||||||
Integer col, Error *err)
|
Integer col, Error *err)
|
||||||
FUNC_API_SINCE(6) FUNC_API_FAST
|
FUNC_API_SINCE(6) FUNC_API_FAST
|
||||||
{
|
{
|
||||||
|
may_trigger_vim_suspend_resume(false);
|
||||||
|
|
||||||
if (button.data == NULL || action.data == NULL) {
|
if (button.data == NULL || action.data == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -428,7 +431,7 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
replace_termcodes(str.data, str.size, &ptr, flags, NULL, CPO_TO_CPO_FLAGS);
|
replace_termcodes(str.data, str.size, &ptr, 0, flags, NULL, CPO_TO_CPO_FLAGS);
|
||||||
return cstr_as_string(ptr);
|
return cstr_as_string(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1686,8 +1689,11 @@ static void write_msg(String message, bool to_err, bool writeln)
|
|||||||
if (c == NL) { \
|
if (c == NL) { \
|
||||||
kv_push(line_buf, NUL); \
|
kv_push(line_buf, NUL); \
|
||||||
msg(line_buf.items); \
|
msg(line_buf.items); \
|
||||||
|
msg_didout = true; \
|
||||||
kv_drop(line_buf, kv_size(line_buf)); \
|
kv_drop(line_buf, kv_size(line_buf)); \
|
||||||
kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \
|
kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \
|
||||||
|
} else if (c == NUL) { \
|
||||||
|
kv_push(line_buf, NL); \
|
||||||
} else { \
|
} else { \
|
||||||
kv_push(line_buf, c); \
|
kv_push(line_buf, c); \
|
||||||
}
|
}
|
||||||
@@ -2173,6 +2179,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
|||||||
linenr_T lnum = statuscol_lnum;
|
linenr_T lnum = statuscol_lnum;
|
||||||
int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul);
|
int num_signs = buf_get_signattrs(wp->w_buffer, lnum, sattrs, &num, &line, &cul);
|
||||||
decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul);
|
decor_redraw_signs(wp->w_buffer, lnum - 1, &num_signs, sattrs, &num, &line, &cul);
|
||||||
|
wp->w_scwidth = win_signcol_count(wp);
|
||||||
|
|
||||||
statuscol.sattrs = sattrs;
|
statuscol.sattrs = sattrs;
|
||||||
statuscol.foldinfo = fold_info(wp, lnum);
|
statuscol.foldinfo = fold_info(wp, lnum);
|
||||||
@@ -2240,7 +2247,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
|||||||
if (highlights) {
|
if (highlights) {
|
||||||
Array hl_values = ARRAY_DICT_INIT;
|
Array hl_values = ARRAY_DICT_INIT;
|
||||||
const char *grpname;
|
const char *grpname;
|
||||||
char user_group[6];
|
char user_group[15]; // strlen("User") + strlen("2147483647") + NUL
|
||||||
|
|
||||||
// If first character doesn't have a defined highlight,
|
// If first character doesn't have a defined highlight,
|
||||||
// add the default highlight at the beginning of the highlight list
|
// add the default highlight at the beginning of the highlight list
|
||||||
|
@@ -275,13 +275,13 @@ Dictionary nvim_win_get_config(Window window, Error *err)
|
|||||||
for (size_t i = 0; i < 8; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
Array tuple = ARRAY_DICT_INIT;
|
Array tuple = ARRAY_DICT_INIT;
|
||||||
|
|
||||||
String s = cstrn_to_string((const char *)config->border_chars[i], sizeof(schar_T));
|
String s = cstrn_to_string(config->border_chars[i], sizeof(schar_T));
|
||||||
|
|
||||||
int hi_id = config->border_hl_ids[i];
|
int hi_id = config->border_hl_ids[i];
|
||||||
char *hi_name = syn_id2name(hi_id);
|
char *hi_name = syn_id2name(hi_id);
|
||||||
if (hi_name[0]) {
|
if (hi_name[0]) {
|
||||||
ADD(tuple, STRING_OBJ(s));
|
ADD(tuple, STRING_OBJ(s));
|
||||||
ADD(tuple, STRING_OBJ(cstr_to_string((const char *)hi_name)));
|
ADD(tuple, STRING_OBJ(cstr_to_string(hi_name)));
|
||||||
ADD(border, ARRAY_OBJ(tuple));
|
ADD(border, ARRAY_OBJ(tuple));
|
||||||
} else {
|
} else {
|
||||||
ADD(border, STRING_OBJ(s));
|
ADD(border, STRING_OBJ(s));
|
||||||
@@ -293,10 +293,9 @@ Dictionary nvim_win_get_config(Window window, Error *err)
|
|||||||
VirtText title_datas = config->title_chunks;
|
VirtText title_datas = config->title_chunks;
|
||||||
for (size_t i = 0; i < title_datas.size; i++) {
|
for (size_t i = 0; i < title_datas.size; i++) {
|
||||||
Array tuple = ARRAY_DICT_INIT;
|
Array tuple = ARRAY_DICT_INIT;
|
||||||
ADD(tuple, CSTR_TO_OBJ((const char *)title_datas.items[i].text));
|
ADD(tuple, CSTR_TO_OBJ(title_datas.items[i].text));
|
||||||
if (title_datas.items[i].hl_id > 0) {
|
if (title_datas.items[i].hl_id > 0) {
|
||||||
ADD(tuple,
|
ADD(tuple, STRING_OBJ(cstr_to_string(syn_id2name(title_datas.items[i].hl_id))));
|
||||||
STRING_OBJ(cstr_to_string((const char *)syn_id2name(title_datas.items[i].hl_id))));
|
|
||||||
}
|
}
|
||||||
ADD(titles, ARRAY_OBJ(tuple));
|
ADD(titles, ARRAY_OBJ(tuple));
|
||||||
}
|
}
|
||||||
|
@@ -855,12 +855,17 @@ static void arg_all_close_unused_windows(arg_all_state_T *aall)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
win_T *wpnext = NULL;
|
win_T *wpnext = NULL;
|
||||||
tabpage_T *tpnext = curtab->tp_next;
|
tabpage_T *tpnext = curtab->tp_next;
|
||||||
for (win_T *wp = firstwin; wp != NULL; wp = wpnext) {
|
// Try to close floating windows first
|
||||||
|
for (win_T *wp = lastwin->w_floating ? lastwin : firstwin; wp != NULL; wp = wpnext) {
|
||||||
int i;
|
int i;
|
||||||
wpnext = wp->w_next;
|
wpnext = wp->w_floating
|
||||||
|
? wp->w_prev->w_floating ? wp->w_prev : firstwin
|
||||||
|
: (wp->w_next == NULL || wp->w_next->w_floating) ? NULL : wp->w_next;
|
||||||
buf_T *buf = wp->w_buffer;
|
buf_T *buf = wp->w_buffer;
|
||||||
if (buf->b_ffname == NULL
|
if (buf->b_ffname == NULL
|
||||||
|| (!aall->keep_tabs && (buf->b_nwindows > 1 || wp->w_width != Columns))) {
|
|| (!aall->keep_tabs
|
||||||
|
&& (buf->b_nwindows > 1 || wp->w_width != Columns
|
||||||
|
|| (wp->w_floating && !is_aucmd_win(wp))))) {
|
||||||
i = aall->opened_len;
|
i = aall->opened_len;
|
||||||
} else {
|
} else {
|
||||||
// check if the buffer in this window is in the arglist
|
// check if the buffer in this window is in the arglist
|
||||||
@@ -915,7 +920,7 @@ static void arg_all_close_unused_windows(arg_all_state_T *aall)
|
|||||||
(void)autowrite(buf, false);
|
(void)autowrite(buf, false);
|
||||||
// Check if autocommands removed the window.
|
// Check if autocommands removed the window.
|
||||||
if (!win_valid(wp) || !bufref_valid(&bufref)) {
|
if (!win_valid(wp) || !bufref_valid(&bufref)) {
|
||||||
wpnext = firstwin; // Start all over...
|
wpnext = lastwin->w_floating ? lastwin : firstwin; // Start all over...
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -928,7 +933,7 @@ static void arg_all_close_unused_windows(arg_all_state_T *aall)
|
|||||||
// check if autocommands removed the next window
|
// check if autocommands removed the next window
|
||||||
if (!win_valid(wpnext)) {
|
if (!win_valid(wpnext)) {
|
||||||
// start all over...
|
// start all over...
|
||||||
wpnext = firstwin;
|
wpnext = lastwin->w_floating ? lastwin : firstwin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -975,6 +980,8 @@ static void arg_all_open_windows(arg_all_state_T *aall, int count)
|
|||||||
if (aall->keep_tabs) {
|
if (aall->keep_tabs) {
|
||||||
aall->new_curwin = wp;
|
aall->new_curwin = wp;
|
||||||
aall->new_curtab = curtab;
|
aall->new_curtab = curtab;
|
||||||
|
} else if (wp->w_floating) {
|
||||||
|
break;
|
||||||
} else if (wp->w_frame->fr_parent != curwin->w_frame->fr_parent) {
|
} else if (wp->w_frame->fr_parent != curwin->w_frame->fr_parent) {
|
||||||
emsg(_("E249: window layout changed unexpectedly"));
|
emsg(_("E249: window layout changed unexpectedly"));
|
||||||
i = count;
|
i = count;
|
||||||
@@ -1089,7 +1096,8 @@ static void do_arg_all(int count, int forceit, int keep_tabs)
|
|||||||
autocmd_no_leave++;
|
autocmd_no_leave++;
|
||||||
last_curwin = curwin;
|
last_curwin = curwin;
|
||||||
last_curtab = curtab;
|
last_curtab = curtab;
|
||||||
win_enter(lastwin, false);
|
// lastwin may be aucmd_win
|
||||||
|
win_enter(lastwin_nofloating(), false);
|
||||||
|
|
||||||
// Open up to "count" windows.
|
// Open up to "count" windows.
|
||||||
arg_all_open_windows(&aall, count);
|
arg_all_open_windows(&aall, count);
|
||||||
@@ -1230,8 +1238,7 @@ static void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rett
|
|||||||
tv_list_alloc_ret(rettv, argcount);
|
tv_list_alloc_ret(rettv, argcount);
|
||||||
if (arglist != NULL) {
|
if (arglist != NULL) {
|
||||||
for (int idx = 0; idx < argcount; idx++) {
|
for (int idx = 0; idx < argcount; idx++) {
|
||||||
tv_list_append_string(rettv->vval.v_list,
|
tv_list_append_string(rettv->vval.v_list, alist_name(&arglist[idx]), -1);
|
||||||
(const char *)alist_name(&arglist[idx]), -1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1267,7 +1274,7 @@ void f_argv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
int idx = (int)tv_get_number_chk(&argvars[0], NULL);
|
int idx = (int)tv_get_number_chk(&argvars[0], NULL);
|
||||||
if (arglist != NULL && idx >= 0 && idx < argcount) {
|
if (arglist != NULL && idx >= 0 && idx < argcount) {
|
||||||
rettv->vval.v_string = xstrdup((const char *)alist_name(&arglist[idx]));
|
rettv->vval.v_string = xstrdup(alist_name(&arglist[idx]));
|
||||||
} else if (idx == -1) {
|
} else if (idx == -1) {
|
||||||
get_arglist_as_rettv(arglist, argcount, rettv);
|
get_arglist_as_rettv(arglist, argcount, rettv);
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
#include "nvim/search.h"
|
#include "nvim/search.h"
|
||||||
#include "nvim/state.h"
|
#include "nvim/state.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
|
#include "nvim/types.h"
|
||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
#include "nvim/ui_compositor.h"
|
#include "nvim/ui_compositor.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
@@ -674,9 +675,9 @@ bool is_aucmd_win(win_T *win)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the event number for event name "start".
|
/// Return the event number for event name "start".
|
||||||
// Return NUM_EVENTS if the event name was not found.
|
/// Return NUM_EVENTS if the event name was not found.
|
||||||
// Return a pointer to the next event name in "end".
|
/// Return a pointer to the next event name in "end".
|
||||||
event_T event_name2nr(const char *start, char **end)
|
event_T event_name2nr(const char *start, char **end)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
@@ -700,6 +701,18 @@ event_T event_name2nr(const char *start, char **end)
|
|||||||
return event_names[i].event;
|
return event_names[i].event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the event number for event name "str".
|
||||||
|
/// Return NUM_EVENTS if the event name was not found.
|
||||||
|
event_T event_name2nr_str(String str)
|
||||||
|
{
|
||||||
|
for (int i = 0; event_names[i].name != NULL; i++) {
|
||||||
|
if (str.size == event_names[i].len && STRNICMP(str.data, event_names[i].name, str.size) == 0) {
|
||||||
|
return event_names[i].event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NUM_EVENTS;
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the name for event
|
/// Return the name for event
|
||||||
///
|
///
|
||||||
/// @param[in] event Event to return name for.
|
/// @param[in] event Event to return name for.
|
||||||
@@ -1421,6 +1434,8 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
|||||||
aco->save_curwin_handle = curwin->handle;
|
aco->save_curwin_handle = curwin->handle;
|
||||||
aco->save_curbuf = curbuf;
|
aco->save_curbuf = curbuf;
|
||||||
aco->save_prevwin_handle = prevwin == NULL ? 0 : prevwin->handle;
|
aco->save_prevwin_handle = prevwin == NULL ? 0 : prevwin->handle;
|
||||||
|
aco->save_State = State;
|
||||||
|
|
||||||
if (win != NULL) {
|
if (win != NULL) {
|
||||||
// There is a window for "buf" in the current tab page, make it the
|
// There is a window for "buf" in the current tab page, make it the
|
||||||
// curwin. This is preferred, it has the least side effects (esp. if
|
// curwin. This is preferred, it has the least side effects (esp. if
|
||||||
@@ -1479,7 +1494,6 @@ void aucmd_restbuf(aco_save_T *aco)
|
|||||||
if (aco->use_aucmd_win_idx >= 0) {
|
if (aco->use_aucmd_win_idx >= 0) {
|
||||||
win_T *awp = aucmd_win[aco->use_aucmd_win_idx].auc_win;
|
win_T *awp = aucmd_win[aco->use_aucmd_win_idx].auc_win;
|
||||||
|
|
||||||
curbuf->b_nwindows--;
|
|
||||||
// Find "awp", it can't be closed, but it may be in another tab page.
|
// Find "awp", it can't be closed, but it may be in another tab page.
|
||||||
// Do not trigger autocommands here.
|
// Do not trigger autocommands here.
|
||||||
block_autocmds();
|
block_autocmds();
|
||||||
@@ -1495,8 +1509,14 @@ void aucmd_restbuf(aco_save_T *aco)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
win_found:
|
win_found:
|
||||||
|
curbuf->b_nwindows--;
|
||||||
|
const bool save_stop_insert_mode = stop_insert_mode;
|
||||||
// May need to stop Insert mode if we were in a prompt buffer.
|
// May need to stop Insert mode if we were in a prompt buffer.
|
||||||
leaving_window(curwin);
|
leaving_window(curwin);
|
||||||
|
// Do not stop Insert mode when already in Insert mode before.
|
||||||
|
if (aco->save_State & MODE_INSERT) {
|
||||||
|
stop_insert_mode = save_stop_insert_mode;
|
||||||
|
}
|
||||||
// Remove the window.
|
// Remove the window.
|
||||||
win_remove(curwin, NULL);
|
win_remove(curwin, NULL);
|
||||||
pmap_del(handle_T)(&window_handles, curwin->handle);
|
pmap_del(handle_T)(&window_handles, curwin->handle);
|
||||||
@@ -1743,6 +1763,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
|||||||
|
|
||||||
// Save the autocmd_* variables and info about the current buffer.
|
// Save the autocmd_* variables and info about the current buffer.
|
||||||
char *save_autocmd_fname = autocmd_fname;
|
char *save_autocmd_fname = autocmd_fname;
|
||||||
|
bool save_autocmd_fname_full = autocmd_fname_full;
|
||||||
int save_autocmd_bufnr = autocmd_bufnr;
|
int save_autocmd_bufnr = autocmd_bufnr;
|
||||||
char *save_autocmd_match = autocmd_match;
|
char *save_autocmd_match = autocmd_match;
|
||||||
int save_autocmd_busy = autocmd_busy;
|
int save_autocmd_busy = autocmd_busy;
|
||||||
@@ -1771,6 +1792,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
|||||||
// Allocate MAXPATHL for when eval_vars() resolves the fullpath.
|
// Allocate MAXPATHL for when eval_vars() resolves the fullpath.
|
||||||
autocmd_fname = xstrnsave(autocmd_fname, MAXPATHL);
|
autocmd_fname = xstrnsave(autocmd_fname, MAXPATHL);
|
||||||
}
|
}
|
||||||
|
autocmd_fname_full = false; // call FullName_save() later
|
||||||
|
|
||||||
// Set the buffer number to be used for <abuf>.
|
// Set the buffer number to be used for <abuf>.
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
@@ -1818,6 +1840,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
|||||||
|| event == EVENT_USER || event == EVENT_WINCLOSED
|
|| event == EVENT_USER || event == EVENT_WINCLOSED
|
||||||
|| event == EVENT_WINRESIZED || event == EVENT_WINSCROLLED) {
|
|| event == EVENT_WINRESIZED || event == EVENT_WINSCROLLED) {
|
||||||
fname = xstrdup(fname);
|
fname = xstrdup(fname);
|
||||||
|
autocmd_fname_full = true; // don't expand it later
|
||||||
} else {
|
} else {
|
||||||
fname = FullName_save(fname, false);
|
fname = FullName_save(fname, false);
|
||||||
}
|
}
|
||||||
@@ -1951,6 +1974,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
|||||||
estack_pop();
|
estack_pop();
|
||||||
xfree(autocmd_fname);
|
xfree(autocmd_fname);
|
||||||
autocmd_fname = save_autocmd_fname;
|
autocmd_fname = save_autocmd_fname;
|
||||||
|
autocmd_fname_full = save_autocmd_fname_full;
|
||||||
autocmd_bufnr = save_autocmd_bufnr;
|
autocmd_bufnr = save_autocmd_bufnr;
|
||||||
autocmd_match = save_autocmd_match;
|
autocmd_match = save_autocmd_match;
|
||||||
current_sctx = save_current_sctx;
|
current_sctx = save_current_sctx;
|
||||||
@@ -2499,7 +2523,7 @@ bool aupat_is_buflocal(char *pat, int patlen)
|
|||||||
|
|
||||||
int aupat_get_buflocal_nr(char *pat, int patlen)
|
int aupat_get_buflocal_nr(char *pat, int patlen)
|
||||||
{
|
{
|
||||||
assert(aupat_is_buflocal((char *)pat, patlen));
|
assert(aupat_is_buflocal(pat, patlen));
|
||||||
|
|
||||||
// "<buffer>"
|
// "<buffer>"
|
||||||
if (patlen == 8) {
|
if (patlen == 8) {
|
||||||
@@ -2713,6 +2737,30 @@ static bool arg_autocmd_flag_get(bool *flag, char **cmd_ptr, char *pattern, int
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When kFalse: VimSuspend should be triggered next.
|
||||||
|
/// When kTrue: VimResume should be triggerd next.
|
||||||
|
/// When kNone: Currently triggering VimSuspend or VimResume.
|
||||||
|
static TriState pending_vimresume = kFalse;
|
||||||
|
|
||||||
|
static void vimresume_event(void **argv)
|
||||||
|
{
|
||||||
|
apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL);
|
||||||
|
pending_vimresume = kFalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trigger VimSuspend or VimResume autocommand.
|
||||||
|
void may_trigger_vim_suspend_resume(bool suspend)
|
||||||
|
{
|
||||||
|
if (suspend && pending_vimresume == kFalse) {
|
||||||
|
pending_vimresume = kNone;
|
||||||
|
apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL);
|
||||||
|
pending_vimresume = kTrue;
|
||||||
|
} else if (!suspend && pending_vimresume == kTrue) {
|
||||||
|
pending_vimresume = kNone;
|
||||||
|
multiqueue_put(main_loop.events, vimresume_event, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// UI Enter
|
// UI Enter
|
||||||
void do_autocmd_uienter(uint64_t chanid, bool attached)
|
void do_autocmd_uienter(uint64_t chanid, bool attached)
|
||||||
{
|
{
|
||||||
|
@@ -32,6 +32,7 @@ typedef struct {
|
|||||||
bufref_T new_curbuf; ///< new curbuf
|
bufref_T new_curbuf; ///< new curbuf
|
||||||
char *globaldir; ///< saved value of globaldir
|
char *globaldir; ///< saved value of globaldir
|
||||||
bool save_VIsual_active; ///< saved VIsual_active
|
bool save_VIsual_active; ///< saved VIsual_active
|
||||||
|
int save_State; ///< saved State
|
||||||
} aco_save_T;
|
} aco_save_T;
|
||||||
|
|
||||||
typedef struct AutoCmd_S AutoCmd;
|
typedef struct AutoCmd_S AutoCmd;
|
||||||
|
@@ -268,7 +268,7 @@ int open_buffer(int read_stdin, exarg_T *eap, int flags_arg)
|
|||||||
int save_bin = curbuf->b_p_bin;
|
int save_bin = curbuf->b_p_bin;
|
||||||
int perm;
|
int perm;
|
||||||
|
|
||||||
perm = os_getperm((const char *)curbuf->b_ffname);
|
perm = os_getperm(curbuf->b_ffname);
|
||||||
if (perm >= 0 && (0 || S_ISFIFO(perm)
|
if (perm >= 0 && (0 || S_ISFIFO(perm)
|
||||||
|| S_ISSOCK(perm)
|
|| S_ISSOCK(perm)
|
||||||
# ifdef OPEN_CHR_FILES
|
# ifdef OPEN_CHR_FILES
|
||||||
@@ -2231,7 +2231,7 @@ int buflist_findpat(const char *pattern, const char *pattern_end, bool unlisted,
|
|||||||
// Repeat this for finding an unlisted buffer if there was no matching
|
// Repeat this for finding an unlisted buffer if there was no matching
|
||||||
// listed buffer.
|
// listed buffer.
|
||||||
|
|
||||||
pat = file_pat_to_reg_pat((char *)pattern, (char *)pattern_end, NULL, false);
|
pat = file_pat_to_reg_pat(pattern, pattern_end, NULL, false);
|
||||||
if (pat == NULL) {
|
if (pat == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -3309,8 +3309,7 @@ void maketitle(void)
|
|||||||
SPACE_FOR_FNAME + 1);
|
SPACE_FOR_FNAME + 1);
|
||||||
buf_p += MIN(size, SPACE_FOR_FNAME);
|
buf_p += MIN(size, SPACE_FOR_FNAME);
|
||||||
} else {
|
} else {
|
||||||
buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname),
|
buf_p += transstr_buf(path_tail(curbuf->b_fname), -1, buf_p, SPACE_FOR_FNAME + 1, true);
|
||||||
-1, buf_p, SPACE_FOR_FNAME + 1, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (bufIsChanged(curbuf)
|
switch (bufIsChanged(curbuf)
|
||||||
@@ -3459,7 +3458,6 @@ void resettitle(void)
|
|||||||
{
|
{
|
||||||
ui_call_set_icon(cstr_as_string(lasticon));
|
ui_call_set_icon(cstr_as_string(lasticon));
|
||||||
ui_call_set_title(cstr_as_string(lasttitle));
|
ui_call_set_title(cstr_as_string(lasttitle));
|
||||||
ui_flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EXITFREE)
|
#if defined(EXITFREE)
|
||||||
@@ -3557,7 +3555,7 @@ void fname_expand(buf_T *buf, char **ffname, char **sfname)
|
|||||||
#ifdef MSWIN
|
#ifdef MSWIN
|
||||||
if (!buf->b_p_bin) {
|
if (!buf->b_p_bin) {
|
||||||
// If the file name is a shortcut file, use the file it links to.
|
// If the file name is a shortcut file, use the file it links to.
|
||||||
char *rfname = os_resolve_shortcut((const char *)(*ffname));
|
char *rfname = os_resolve_shortcut(*ffname);
|
||||||
if (rfname != NULL) {
|
if (rfname != NULL) {
|
||||||
xfree(*ffname);
|
xfree(*ffname);
|
||||||
*ffname = rfname;
|
*ffname = rfname;
|
||||||
@@ -3612,21 +3610,28 @@ void ex_buffer_all(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
tpnext = curtab->tp_next;
|
tpnext = curtab->tp_next;
|
||||||
for (wp = firstwin; wp != NULL; wp = wpnext) {
|
// Try to close floating windows first
|
||||||
wpnext = wp->w_next;
|
for (wp = lastwin->w_floating ? lastwin : firstwin; wp != NULL; wp = wpnext) {
|
||||||
|
wpnext = wp->w_floating
|
||||||
|
? wp->w_prev->w_floating ? wp->w_prev : firstwin
|
||||||
|
: (wp->w_next == NULL || wp->w_next->w_floating) ? NULL : wp->w_next;
|
||||||
if ((wp->w_buffer->b_nwindows > 1
|
if ((wp->w_buffer->b_nwindows > 1
|
||||||
|
|| wp->w_floating
|
||||||
|| ((cmdmod.cmod_split & WSP_VERT)
|
|| ((cmdmod.cmod_split & WSP_VERT)
|
||||||
? wp->w_height + wp->w_hsep_height + wp->w_status_height < Rows - p_ch
|
? wp->w_height + wp->w_hsep_height + wp->w_status_height < Rows - p_ch
|
||||||
- tabline_height() - global_stl_height()
|
- tabline_height() - global_stl_height()
|
||||||
: wp->w_width != Columns)
|
: wp->w_width != Columns)
|
||||||
|| (had_tab > 0 && wp != firstwin))
|
|| (had_tab > 0 && wp != firstwin))
|
||||||
&& !ONE_WINDOW
|
&& !ONE_WINDOW
|
||||||
&& !(wp->w_closing
|
&& !(wp->w_closing || wp->w_buffer->b_locked > 0)
|
||||||
|| wp->w_buffer->b_locked > 0)) {
|
&& !is_aucmd_win(wp)) {
|
||||||
win_close(wp, false, false);
|
if (win_close(wp, false, false) == FAIL) {
|
||||||
wpnext = firstwin; // just in case an autocommand does
|
break;
|
||||||
// something strange with windows
|
}
|
||||||
tpnext = first_tabpage; // start all over...
|
// Just in case an autocommand does something strange with
|
||||||
|
// windows: start all over...
|
||||||
|
wpnext = lastwin->w_floating ? lastwin : firstwin;
|
||||||
|
tpnext = first_tabpage;
|
||||||
open_wins = 0;
|
open_wins = 0;
|
||||||
} else {
|
} else {
|
||||||
open_wins++;
|
open_wins++;
|
||||||
@@ -3646,7 +3651,8 @@ void ex_buffer_all(exarg_T *eap)
|
|||||||
//
|
//
|
||||||
// Don't execute Win/Buf Enter/Leave autocommands here.
|
// Don't execute Win/Buf Enter/Leave autocommands here.
|
||||||
autocmd_no_enter++;
|
autocmd_no_enter++;
|
||||||
win_enter(lastwin, false);
|
// lastwin may be aucmd_win
|
||||||
|
win_enter(lastwin_nofloating(), false);
|
||||||
autocmd_no_leave++;
|
autocmd_no_leave++;
|
||||||
for (buf = firstbuf; buf != NULL && open_wins < count; buf = buf->b_next) {
|
for (buf = firstbuf; buf != NULL && open_wins < count; buf = buf->b_next) {
|
||||||
// Check if this buffer needs a window
|
// Check if this buffer needs a window
|
||||||
@@ -3664,7 +3670,7 @@ void ex_buffer_all(exarg_T *eap)
|
|||||||
} else {
|
} else {
|
||||||
// Check if this buffer already has a window
|
// Check if this buffer already has a window
|
||||||
for (wp = firstwin; wp != NULL; wp = wp->w_next) {
|
for (wp = firstwin; wp != NULL; wp = wp->w_next) {
|
||||||
if (wp->w_buffer == buf) {
|
if (!wp->w_floating && wp->w_buffer == buf) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3738,7 +3744,7 @@ void ex_buffer_all(exarg_T *eap)
|
|||||||
// Close superfluous windows.
|
// Close superfluous windows.
|
||||||
for (wp = lastwin; open_wins > count;) {
|
for (wp = lastwin; open_wins > count;) {
|
||||||
r = (buf_hide(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
|
r = (buf_hide(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
|
||||||
|| autowrite(wp->w_buffer, false) == OK);
|
|| autowrite(wp->w_buffer, false) == OK) && !is_aucmd_win(wp);
|
||||||
if (!win_valid(wp)) {
|
if (!win_valid(wp)) {
|
||||||
// BufWrite Autocommands made the window invalid, start over
|
// BufWrite Autocommands made the window invalid, start over
|
||||||
wp = lastwin;
|
wp = lastwin;
|
||||||
|
@@ -1193,6 +1193,7 @@ struct window_S {
|
|||||||
int w_hsep_height; // Number of horizontal separator rows (0 or 1)
|
int w_hsep_height; // Number of horizontal separator rows (0 or 1)
|
||||||
int w_vsep_width; // Number of vertical separator columns (0 or 1).
|
int w_vsep_width; // Number of vertical separator columns (0 or 1).
|
||||||
pos_save_T w_save_cursor; // backup of cursor pos and topline
|
pos_save_T w_save_cursor; // backup of cursor pos and topline
|
||||||
|
bool w_do_win_fix_cursor; // if true cursor may be invalid
|
||||||
|
|
||||||
int w_winrow_off; ///< offset from winrow to the inner window area
|
int w_winrow_off; ///< offset from winrow to the inner window area
|
||||||
int w_wincol_off; ///< offset from wincol to the inner window area
|
int w_wincol_off; ///< offset from wincol to the inner window area
|
||||||
@@ -1223,6 +1224,9 @@ struct window_S {
|
|||||||
|
|
||||||
bool w_viewport_invalid;
|
bool w_viewport_invalid;
|
||||||
linenr_T w_viewport_last_topline; // topline when the viewport was last updated
|
linenr_T w_viewport_last_topline; // topline when the viewport was last updated
|
||||||
|
linenr_T w_viewport_last_botline; // botline when the viewport was last updated
|
||||||
|
linenr_T w_viewport_last_topfill; // topfill when the viewport was last updated
|
||||||
|
linenr_T w_viewport_last_skipcol; // skipcol when the viewport was last updated
|
||||||
|
|
||||||
// w_cline_height is the number of physical lines taken by the buffer line
|
// w_cline_height is the number of physical lines taken by the buffer line
|
||||||
// that the cursor is on. We use this to avoid extra calls to plines_win().
|
// that the cursor is on. We use this to avoid extra calls to plines_win().
|
||||||
@@ -1287,8 +1291,9 @@ struct window_S {
|
|||||||
linenr_T w_stl_line_count; // line count when last redrawn
|
linenr_T w_stl_line_count; // line count when last redrawn
|
||||||
int w_stl_topfill; // topfill when last redrawn
|
int w_stl_topfill; // topfill when last redrawn
|
||||||
char w_stl_empty; // true if elements show 0-1 (empty line)
|
char w_stl_empty; // true if elements show 0-1 (empty line)
|
||||||
int w_stl_state; // State when last redrawn
|
|
||||||
int w_stl_recording; // reg_recording when last redrawn
|
int w_stl_recording; // reg_recording when last redrawn
|
||||||
|
int w_stl_state; // get_real_state() when last redrawn
|
||||||
|
int w_stl_visual_mode; // VIsual_mode when last redrawn
|
||||||
|
|
||||||
int w_alt_fnum; // alternate file (for # and CTRL-^)
|
int w_alt_fnum; // alternate file (for # and CTRL-^)
|
||||||
|
|
||||||
|
@@ -297,7 +297,12 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, linenr_T
|
|||||||
if (wp->w_lines[i].wl_lnum >= lnum) {
|
if (wp->w_lines[i].wl_lnum >= lnum) {
|
||||||
// Do not change wl_lnum at index zero, it is used to
|
// Do not change wl_lnum at index zero, it is used to
|
||||||
// compare with w_topline. Invalidate it instead.
|
// compare with w_topline. Invalidate it instead.
|
||||||
if (wp->w_lines[i].wl_lnum < lnume || i == 0) {
|
// If the buffer has virt_lines, invalidate the line
|
||||||
|
// after the changed lines as the virt_lines for a
|
||||||
|
// changed line may become invalid.
|
||||||
|
if (i == 0 || wp->w_lines[i].wl_lnum < lnume
|
||||||
|
|| (wp->w_lines[i].wl_lnum == lnume
|
||||||
|
&& wp->w_buffer->b_virt_line_blocks > 0)) {
|
||||||
// line included in change
|
// line included in change
|
||||||
wp->w_lines[i].wl_valid = false;
|
wp->w_lines[i].wl_valid = false;
|
||||||
} else if (xtra != 0) {
|
} else if (xtra != 0) {
|
||||||
@@ -1311,7 +1316,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find start of middle part
|
// find start of middle part
|
||||||
(void)copy_option_part(&p, (char *)lead_middle, COM_MAX_LEN, ",");
|
(void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
|
||||||
require_blank = false;
|
require_blank = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1322,7 +1327,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
|||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
(void)copy_option_part(&p, (char *)lead_middle, COM_MAX_LEN, ",");
|
(void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
|
||||||
|
|
||||||
while (*p && p[-1] != ':') { // find end of end flags
|
while (*p && p[-1] != ':') { // find end of end flags
|
||||||
// Check whether we allow automatic ending of comments
|
// Check whether we allow automatic ending of comments
|
||||||
@@ -1331,7 +1336,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
|||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
size_t n = copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ",");
|
size_t n = copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
|
||||||
|
|
||||||
if (end_comment_pending == -1) { // we can set it now
|
if (end_comment_pending == -1) { // we can set it now
|
||||||
end_comment_pending = (unsigned char)lead_end[n - 1];
|
end_comment_pending = (unsigned char)lead_end[n - 1];
|
||||||
@@ -1352,7 +1357,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
|||||||
// Doing "o" on a start of comment inserts the middle leader.
|
// Doing "o" on a start of comment inserts the middle leader.
|
||||||
if (lead_len > 0) {
|
if (lead_len > 0) {
|
||||||
if (current_flag == COM_START) {
|
if (current_flag == COM_START) {
|
||||||
lead_repl = (char *)lead_middle;
|
lead_repl = lead_middle;
|
||||||
lead_repl_len = (int)strlen(lead_middle);
|
lead_repl_len = (int)strlen(lead_middle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -81,7 +81,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
|||||||
// allow double close, even though we can't say what parts was valid.
|
// allow double close, even though we can't say what parts was valid.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*error = (const char *)e_invchan;
|
*error = e_invchan;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,19 +91,19 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
|||||||
if (chan->is_rpc) {
|
if (chan->is_rpc) {
|
||||||
rpc_close(chan);
|
rpc_close(chan);
|
||||||
} else if (part == kChannelPartRpc) {
|
} else if (part == kChannelPartRpc) {
|
||||||
*error = (const char *)e_invstream;
|
*error = e_invstream;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if ((part == kChannelPartStdin || part == kChannelPartStdout)
|
} else if ((part == kChannelPartStdin || part == kChannelPartStdout)
|
||||||
&& chan->is_rpc) {
|
&& chan->is_rpc) {
|
||||||
*error = (const char *)e_invstreamrpc;
|
*error = e_invstreamrpc;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chan->streamtype) {
|
switch (chan->streamtype) {
|
||||||
case kChannelStreamSocket:
|
case kChannelStreamSocket:
|
||||||
if (!close_main) {
|
if (!close_main) {
|
||||||
*error = (const char *)e_invstream;
|
*error = e_invstream;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stream_may_close(&chan->stream.socket);
|
stream_may_close(&chan->stream.socket);
|
||||||
@@ -134,14 +134,14 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
|||||||
stream_may_close(&chan->stream.stdio.out);
|
stream_may_close(&chan->stream.stdio.out);
|
||||||
}
|
}
|
||||||
if (part == kChannelPartStderr) {
|
if (part == kChannelPartStderr) {
|
||||||
*error = (const char *)e_invstream;
|
*error = e_invstream;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kChannelStreamStderr:
|
case kChannelStreamStderr:
|
||||||
if (part != kChannelPartAll && part != kChannelPartStderr) {
|
if (part != kChannelPartAll && part != kChannelPartStderr) {
|
||||||
*error = (const char *)e_invstream;
|
*error = e_invstream;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!chan->stream.err.closed) {
|
if (!chan->stream.err.closed) {
|
||||||
@@ -156,7 +156,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
|||||||
|
|
||||||
case kChannelStreamInternal:
|
case kChannelStreamInternal:
|
||||||
if (!close_main) {
|
if (!close_main) {
|
||||||
*error = (const char *)e_invstream;
|
*error = e_invstream;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (chan->term) {
|
if (chan->term) {
|
||||||
@@ -309,6 +309,7 @@ static void close_cb(Stream *stream, void *data)
|
|||||||
///
|
///
|
||||||
/// @param[in] argv Arguments vector specifying the command to run,
|
/// @param[in] argv Arguments vector specifying the command to run,
|
||||||
/// NULL-terminated
|
/// NULL-terminated
|
||||||
|
/// @param[in] exepath The path to the executable. If NULL, use `argv[0]`.
|
||||||
/// @param[in] on_stdout Callback to read the job's stdout
|
/// @param[in] on_stdout Callback to read the job's stdout
|
||||||
/// @param[in] on_stderr Callback to read the job's stderr
|
/// @param[in] on_stderr Callback to read the job's stderr
|
||||||
/// @param[in] on_exit Callback to receive the job's exit status
|
/// @param[in] on_exit Callback to receive the job's exit status
|
||||||
@@ -330,10 +331,11 @@ static void close_cb(Stream *stream, void *data)
|
|||||||
/// < 0 if the job can't start
|
/// < 0 if the job can't start
|
||||||
///
|
///
|
||||||
/// @returns [allocated] channel
|
/// @returns [allocated] channel
|
||||||
Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader on_stderr,
|
Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_stdout,
|
||||||
Callback on_exit, bool pty, bool rpc, bool overlapped, bool detach,
|
CallbackReader on_stderr, Callback on_exit, bool pty, bool rpc,
|
||||||
ChannelStdinMode stdin_mode, const char *cwd, uint16_t pty_width,
|
bool overlapped, bool detach, ChannelStdinMode stdin_mode,
|
||||||
uint16_t pty_height, dict_T *env, varnumber_T *status_out)
|
const char *cwd, uint16_t pty_width, uint16_t pty_height, dict_T *env,
|
||||||
|
varnumber_T *status_out)
|
||||||
{
|
{
|
||||||
Channel *chan = channel_alloc(kChannelStreamProc);
|
Channel *chan = channel_alloc(kChannelStreamProc);
|
||||||
chan->on_data = on_stdout;
|
chan->on_data = on_stdout;
|
||||||
@@ -364,6 +366,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
|
|||||||
|
|
||||||
Process *proc = &chan->stream.proc;
|
Process *proc = &chan->stream.proc;
|
||||||
proc->argv = argv;
|
proc->argv = argv;
|
||||||
|
proc->exepath = exepath;
|
||||||
proc->cb = channel_process_exit_cb;
|
proc->cb = channel_process_exit_cb;
|
||||||
proc->events = chan->events;
|
proc->events = chan->events;
|
||||||
proc->detach = detach;
|
proc->detach = detach;
|
||||||
@@ -371,7 +374,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
|
|||||||
proc->env = env;
|
proc->env = env;
|
||||||
proc->overlapped = overlapped;
|
proc->overlapped = overlapped;
|
||||||
|
|
||||||
char *cmd = xstrdup(proc->argv[0]);
|
char *cmd = xstrdup(process_get_exepath(proc));
|
||||||
bool has_out, has_err;
|
bool has_out, has_err;
|
||||||
if (proc->type == kProcessTypePty) {
|
if (proc->type == kProcessTypePty) {
|
||||||
has_out = true;
|
has_out = true;
|
||||||
|
@@ -389,7 +389,7 @@ size_t transstr_buf(const char *const s, const ssize_t slen, char *const buf, co
|
|||||||
} else if (*p == TAB && !untab) {
|
} else if (*p == TAB && !untab) {
|
||||||
*buf_p++ = *p++;
|
*buf_p++ = *p++;
|
||||||
} else {
|
} else {
|
||||||
const char *const tb = (const char *)transchar_byte((uint8_t)(*p++));
|
const char *const tb = transchar_byte((uint8_t)(*p++));
|
||||||
const size_t tb_len = strlen(tb);
|
const size_t tb_len = strlen(tb);
|
||||||
if (buf_p + tb_len > buf_e) {
|
if (buf_p + tb_len > buf_e) {
|
||||||
break; // Exceeded `buf` size.
|
break; // Exceeded `buf` size.
|
||||||
@@ -645,8 +645,8 @@ size_t transchar_hex(char *const buf, const int c)
|
|||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
buf[i++] = '<';
|
buf[i++] = '<';
|
||||||
if (c > 255) {
|
if (c > 0xFF) {
|
||||||
if (c > 255 * 256) {
|
if (c > 0xFFFF) {
|
||||||
buf[i++] = (char)nr2hex((unsigned)c >> 20);
|
buf[i++] = (char)nr2hex((unsigned)c >> 20);
|
||||||
buf[i++] = (char)nr2hex((unsigned)c >> 16);
|
buf[i++] = (char)nr2hex((unsigned)c >> 16);
|
||||||
}
|
}
|
||||||
@@ -858,8 +858,10 @@ bool vim_iswordp_buf(const char *const p, buf_T *const buf)
|
|||||||
return vim_iswordc_buf(c, buf);
|
return vim_iswordc_buf(c, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check that "c" is a valid file-name character.
|
/// Check that "c" is a valid file-name character as specified with the
|
||||||
|
/// 'isfname' option.
|
||||||
/// Assume characters above 0x100 are valid (multi-byte).
|
/// Assume characters above 0x100 are valid (multi-byte).
|
||||||
|
/// To be used for commands like "gf".
|
||||||
///
|
///
|
||||||
/// @param c character to check
|
/// @param c character to check
|
||||||
bool vim_isfilec(int c)
|
bool vim_isfilec(int c)
|
||||||
@@ -868,6 +870,14 @@ bool vim_isfilec(int c)
|
|||||||
return c >= 0x100 || (c > 0 && (g_chartab[c] & CT_FNAME_CHAR));
|
return c >= 0x100 || (c > 0 && (g_chartab[c] & CT_FNAME_CHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if "c" is a valid file-name character, including characters left
|
||||||
|
/// out of 'isfname' to make "gf" work, such as comma, space, '@', etc.
|
||||||
|
bool vim_is_fname_char(int c)
|
||||||
|
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
|
{
|
||||||
|
return vim_isfilec(c) || c == ',' || c == ' ' || c == '@';
|
||||||
|
}
|
||||||
|
|
||||||
/// Check that "c" is a valid file-name character or a wildcard character
|
/// Check that "c" is a valid file-name character or a wildcard character
|
||||||
/// Assume characters above 0x100 are valid (multi-byte).
|
/// Assume characters above 0x100 are valid (multi-byte).
|
||||||
/// Explicitly interpret ']' as a wildcard character as path_has_wildcard("]")
|
/// Explicitly interpret ']' as a wildcard character as path_has_wildcard("]")
|
||||||
@@ -1360,7 +1370,7 @@ char *skiptowhite(const char *p)
|
|||||||
/// @param p
|
/// @param p
|
||||||
///
|
///
|
||||||
/// @return Pointer to the next whitespace character.
|
/// @return Pointer to the next whitespace character.
|
||||||
char *skiptowhite_esc(char *p)
|
char *skiptowhite_esc(const char *p)
|
||||||
FUNC_ATTR_PURE
|
FUNC_ATTR_PURE
|
||||||
{
|
{
|
||||||
while (*p != ' ' && *p != '\t' && *p != NUL) {
|
while (*p != ' ' && *p != '\t' && *p != NUL) {
|
||||||
@@ -1369,7 +1379,7 @@ char *skiptowhite_esc(char *p)
|
|||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return p;
|
return (char *)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skip over text until '\n' or NUL.
|
/// Skip over text until '\n' or NUL.
|
||||||
|
@@ -616,14 +616,14 @@ static void redraw_wildmenu(expand_T *xp, int num_matches, char **matches, int m
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next or prev cmdline completion match. The index of the match is set
|
/// Get the next or prev cmdline completion match. The index of the match is set
|
||||||
/// in "p_findex"
|
/// in "xp->xp_selected"
|
||||||
static char *get_next_or_prev_match(int mode, expand_T *xp, int *p_findex, char *orig_save)
|
static char *get_next_or_prev_match(int mode, expand_T *xp)
|
||||||
{
|
{
|
||||||
if (xp->xp_numfiles <= 0) {
|
if (xp->xp_numfiles <= 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int findex = *p_findex;
|
int findex = xp->xp_selected;
|
||||||
|
|
||||||
if (mode == WILD_PREV) {
|
if (mode == WILD_PREV) {
|
||||||
if (findex == -1) {
|
if (findex == -1) {
|
||||||
@@ -677,14 +677,14 @@ static char *get_next_or_prev_match(int mode, expand_T *xp, int *p_findex, char
|
|||||||
|
|
||||||
// When wrapping around, return the original string, set findex to -1.
|
// When wrapping around, return the original string, set findex to -1.
|
||||||
if (findex < 0) {
|
if (findex < 0) {
|
||||||
if (orig_save == NULL) {
|
if (xp->xp_orig == NULL) {
|
||||||
findex = xp->xp_numfiles - 1;
|
findex = xp->xp_numfiles - 1;
|
||||||
} else {
|
} else {
|
||||||
findex = -1;
|
findex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (findex >= xp->xp_numfiles) {
|
if (findex >= xp->xp_numfiles) {
|
||||||
if (orig_save == NULL) {
|
if (xp->xp_orig == NULL) {
|
||||||
findex = 0;
|
findex = 0;
|
||||||
} else {
|
} else {
|
||||||
findex = -1;
|
findex = -1;
|
||||||
@@ -696,9 +696,9 @@ static char *get_next_or_prev_match(int mode, expand_T *xp, int *p_findex, char
|
|||||||
} else if (p_wmnu) {
|
} else if (p_wmnu) {
|
||||||
redraw_wildmenu(xp, xp->xp_numfiles, xp->xp_files, findex, cmd_showtail);
|
redraw_wildmenu(xp, xp->xp_numfiles, xp->xp_files, findex, cmd_showtail);
|
||||||
}
|
}
|
||||||
*p_findex = findex;
|
xp->xp_selected = findex;
|
||||||
|
|
||||||
return xstrdup(findex == -1 ? orig_save : xp->xp_files[findex]);
|
return xstrdup(findex == -1 ? xp->xp_orig : xp->xp_files[findex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start the command-line expansion and get the matches.
|
/// Start the command-line expansion and get the matches.
|
||||||
@@ -805,8 +805,8 @@ static char *find_longest_match(expand_T *xp, int options)
|
|||||||
/// Return NULL for failure.
|
/// Return NULL for failure.
|
||||||
///
|
///
|
||||||
/// "orig" is the originally expanded string, copied to allocated memory. It
|
/// "orig" is the originally expanded string, copied to allocated memory. It
|
||||||
/// should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
|
/// should either be kept in "xp->xp_orig" or freed. When "mode" is WILD_NEXT
|
||||||
/// WILD_PREV "orig" should be NULL.
|
/// or WILD_PREV "orig" should be NULL.
|
||||||
///
|
///
|
||||||
/// Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
|
/// Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
|
||||||
/// is WILD_EXPAND_FREE or WILD_ALL.
|
/// is WILD_EXPAND_FREE or WILD_ALL.
|
||||||
@@ -841,45 +841,43 @@ static char *find_longest_match(expand_T *xp, int options)
|
|||||||
char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
|
char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
|
||||||
{
|
{
|
||||||
char *ss = NULL;
|
char *ss = NULL;
|
||||||
static int findex;
|
|
||||||
static char *orig_save = NULL; // kept value of orig
|
|
||||||
int orig_saved = false;
|
int orig_saved = false;
|
||||||
|
|
||||||
// first handle the case of using an old match
|
// first handle the case of using an old match
|
||||||
if (mode == WILD_NEXT || mode == WILD_PREV
|
if (mode == WILD_NEXT || mode == WILD_PREV
|
||||||
|| mode == WILD_PAGEUP || mode == WILD_PAGEDOWN
|
|| mode == WILD_PAGEUP || mode == WILD_PAGEDOWN
|
||||||
|| mode == WILD_PUM_WANT) {
|
|| mode == WILD_PUM_WANT) {
|
||||||
return get_next_or_prev_match(mode, xp, &findex, orig_save);
|
return get_next_or_prev_match(mode, xp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == WILD_CANCEL) {
|
if (mode == WILD_CANCEL) {
|
||||||
ss = xstrdup(orig_save ? orig_save : "");
|
ss = xstrdup(xp->xp_orig ? xp->xp_orig : "");
|
||||||
} else if (mode == WILD_APPLY) {
|
} else if (mode == WILD_APPLY) {
|
||||||
ss = xstrdup(findex == -1
|
ss = xstrdup(xp->xp_selected == -1
|
||||||
? (orig_save ? orig_save : "")
|
? (xp->xp_orig ? xp->xp_orig : "")
|
||||||
: xp->xp_files[findex]);
|
: xp->xp_files[xp->xp_selected]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free old names
|
// free old names
|
||||||
if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) {
|
if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) {
|
||||||
FreeWild(xp->xp_numfiles, xp->xp_files);
|
FreeWild(xp->xp_numfiles, xp->xp_files);
|
||||||
xp->xp_numfiles = -1;
|
xp->xp_numfiles = -1;
|
||||||
XFREE_CLEAR(orig_save);
|
XFREE_CLEAR(xp->xp_orig);
|
||||||
|
|
||||||
// The entries from xp_files may be used in the PUM, remove it.
|
// The entries from xp_files may be used in the PUM, remove it.
|
||||||
if (compl_match_array != NULL) {
|
if (compl_match_array != NULL) {
|
||||||
cmdline_pum_remove();
|
cmdline_pum_remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
findex = 0;
|
xp->xp_selected = 0;
|
||||||
|
|
||||||
if (mode == WILD_FREE) { // only release file name
|
if (mode == WILD_FREE) { // only release file name
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) {
|
if (xp->xp_numfiles == -1 && mode != WILD_APPLY && mode != WILD_CANCEL) {
|
||||||
xfree(orig_save);
|
xfree(xp->xp_orig);
|
||||||
orig_save = orig;
|
xp->xp_orig = orig;
|
||||||
orig_saved = true;
|
orig_saved = true;
|
||||||
|
|
||||||
ss = ExpandOne_start(mode, xp, str, options);
|
ss = ExpandOne_start(mode, xp, str, options);
|
||||||
@@ -888,7 +886,7 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
|
|||||||
// Find longest common part
|
// Find longest common part
|
||||||
if (mode == WILD_LONGEST && xp->xp_numfiles > 0) {
|
if (mode == WILD_LONGEST && xp->xp_numfiles > 0) {
|
||||||
ss = find_longest_match(xp, options);
|
ss = find_longest_match(xp, options);
|
||||||
findex = -1; // next p_wc gets first one
|
xp->xp_selected = -1; // next p_wc gets first one
|
||||||
}
|
}
|
||||||
|
|
||||||
// Concatenate all matching names. Unless interrupted, this can be slow
|
// Concatenate all matching names. Unless interrupted, this can be slow
|
||||||
@@ -913,7 +911,7 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
|
|||||||
ExpandCleanup(xp);
|
ExpandCleanup(xp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free "orig" if it wasn't stored in "orig_save".
|
// Free "orig" if it wasn't stored in "xp->xp_orig".
|
||||||
if (!orig_saved) {
|
if (!orig_saved) {
|
||||||
xfree(orig);
|
xfree(orig);
|
||||||
}
|
}
|
||||||
@@ -937,6 +935,7 @@ void ExpandCleanup(expand_T *xp)
|
|||||||
FreeWild(xp->xp_numfiles, xp->xp_files);
|
FreeWild(xp->xp_numfiles, xp->xp_files);
|
||||||
xp->xp_numfiles = -1;
|
xp->xp_numfiles = -1;
|
||||||
}
|
}
|
||||||
|
XFREE_CLEAR(xp->xp_orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Display one line of completion matches. Multiple matches are displayed in
|
/// Display one line of completion matches. Multiple matches are displayed in
|
||||||
@@ -959,7 +958,7 @@ static void showmatches_oneline(expand_T *xp, char **matches, int numMatches, in
|
|||||||
msg_outtrans_attr(matches[j], HL_ATTR(HLF_D));
|
msg_outtrans_attr(matches[j], HL_ATTR(HLF_D));
|
||||||
p = matches[j] + strlen(matches[j]) + 1;
|
p = matches[j] + strlen(matches[j]) + 1;
|
||||||
msg_advance(maxlen + 1);
|
msg_advance(maxlen + 1);
|
||||||
msg_puts((const char *)p);
|
msg_puts(p);
|
||||||
msg_advance(maxlen + 3);
|
msg_advance(maxlen + 3);
|
||||||
msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
|
msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
|
||||||
break;
|
break;
|
||||||
@@ -1438,7 +1437,7 @@ static const char *set_cmd_index(const char *cmd, exarg_T *eap, expand_T *xp, in
|
|||||||
p = cmd + 1;
|
p = cmd + 1;
|
||||||
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
|
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
|
||||||
eap->cmd = (char *)cmd;
|
eap->cmd = (char *)cmd;
|
||||||
p = (const char *)find_ucmd(eap, (char *)p, NULL, xp, complp);
|
p = find_ucmd(eap, (char *)p, NULL, xp, complp);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
eap->cmdidx = CMD_SIZE; // Ambiguous user command.
|
eap->cmdidx = CMD_SIZE; // Ambiguous user command.
|
||||||
}
|
}
|
||||||
@@ -1464,7 +1463,7 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use
|
|||||||
// Allow spaces within back-quotes to count as part of the argument
|
// Allow spaces within back-quotes to count as part of the argument
|
||||||
// being expanded.
|
// being expanded.
|
||||||
xp->xp_pattern = skipwhite(arg);
|
xp->xp_pattern = skipwhite(arg);
|
||||||
const char *p = (const char *)xp->xp_pattern;
|
const char *p = xp->xp_pattern;
|
||||||
while (*p != NUL) {
|
while (*p != NUL) {
|
||||||
int c = utf_ptr2char(p);
|
int c = utf_ptr2char(p);
|
||||||
if (c == '\\' && p[1] != NUL) {
|
if (c == '\\' && p[1] != NUL) {
|
||||||
@@ -1517,7 +1516,7 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use
|
|||||||
|
|
||||||
// Check for environment variable.
|
// Check for environment variable.
|
||||||
if (*xp->xp_pattern == '$') {
|
if (*xp->xp_pattern == '$') {
|
||||||
for (p = (const char *)xp->xp_pattern + 1; *p != NUL; p++) {
|
for (p = xp->xp_pattern + 1; *p != NUL; p++) {
|
||||||
if (!vim_isIDc((uint8_t)(*p))) {
|
if (!vim_isIDc((uint8_t)(*p))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1533,12 +1532,11 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use
|
|||||||
}
|
}
|
||||||
// Check for user names.
|
// Check for user names.
|
||||||
if (*xp->xp_pattern == '~') {
|
if (*xp->xp_pattern == '~') {
|
||||||
for (p = (const char *)xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {}
|
for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {}
|
||||||
// Complete ~user only if it partially matches a user name.
|
// Complete ~user only if it partially matches a user name.
|
||||||
// A full match ~user<Tab> will be replaced by user's home
|
// A full match ~user<Tab> will be replaced by user's home
|
||||||
// directory i.e. something like ~user<Tab> -> /home/user/
|
// directory i.e. something like ~user<Tab> -> /home/user/
|
||||||
if (*p == NUL && p > (const char *)xp->xp_pattern + 1
|
if (*p == NUL && p > xp->xp_pattern + 1 && match_user(xp->xp_pattern + 1) >= 1) {
|
||||||
&& match_user(xp->xp_pattern + 1) >= 1) {
|
|
||||||
xp->xp_context = EXPAND_USER;
|
xp->xp_context = EXPAND_USER;
|
||||||
xp->xp_pattern++;
|
xp->xp_pattern++;
|
||||||
}
|
}
|
||||||
@@ -1550,13 +1548,13 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use
|
|||||||
static const char *set_context_in_filter_cmd(expand_T *xp, const char *arg)
|
static const char *set_context_in_filter_cmd(expand_T *xp, const char *arg)
|
||||||
{
|
{
|
||||||
if (*arg != NUL) {
|
if (*arg != NUL) {
|
||||||
arg = (const char *)skip_vimgrep_pat((char *)arg, NULL, NULL);
|
arg = skip_vimgrep_pat((char *)arg, NULL, NULL);
|
||||||
}
|
}
|
||||||
if (arg == NULL || *arg == NUL) {
|
if (arg == NULL || *arg == NUL) {
|
||||||
xp->xp_context = EXPAND_NOTHING;
|
xp->xp_context = EXPAND_NOTHING;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (const char *)skipwhite(arg);
|
return skipwhite(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the completion context for the :match command. Returns a pointer to the
|
/// Set the completion context for the :match command. Returns a pointer to the
|
||||||
@@ -1566,13 +1564,13 @@ static const char *set_context_in_match_cmd(expand_T *xp, const char *arg)
|
|||||||
if (*arg == NUL || !ends_excmd(*arg)) {
|
if (*arg == NUL || !ends_excmd(*arg)) {
|
||||||
// also complete "None"
|
// also complete "None"
|
||||||
set_context_in_echohl_cmd(xp, arg);
|
set_context_in_echohl_cmd(xp, arg);
|
||||||
arg = (const char *)skipwhite(skiptowhite(arg));
|
arg = skipwhite(skiptowhite(arg));
|
||||||
if (*arg != NUL) {
|
if (*arg != NUL) {
|
||||||
xp->xp_context = EXPAND_NOTHING;
|
xp->xp_context = EXPAND_NOTHING;
|
||||||
arg = (const char *)skip_regexp((char *)arg + 1, (uint8_t)(*arg), magic_isset());
|
arg = skip_regexp((char *)arg + 1, (uint8_t)(*arg), magic_isset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (const char *)find_nextcmd(arg);
|
return find_nextcmd(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a pointer to the next command after a :global or a :v command.
|
/// Returns a pointer to the next command after a :global or a :v command.
|
||||||
@@ -1605,7 +1603,7 @@ static const char *find_cmd_after_substitute_cmd(const char *arg)
|
|||||||
if (delim) {
|
if (delim) {
|
||||||
// Skip "from" part.
|
// Skip "from" part.
|
||||||
arg++;
|
arg++;
|
||||||
arg = (const char *)skip_regexp((char *)arg, delim, magic_isset());
|
arg = skip_regexp((char *)arg, delim, magic_isset());
|
||||||
|
|
||||||
if (arg[0] != NUL && arg[0] == delim) {
|
if (arg[0] != NUL && arg[0] == delim) {
|
||||||
// Skip "to" part.
|
// Skip "to" part.
|
||||||
@@ -1637,7 +1635,7 @@ static const char *find_cmd_after_substitute_cmd(const char *arg)
|
|||||||
static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg)
|
static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg)
|
||||||
{
|
{
|
||||||
// Skip count.
|
// Skip count.
|
||||||
arg = (const char *)skipwhite(skipdigits(arg));
|
arg = skipwhite(skipdigits(arg));
|
||||||
if (*arg != '/') {
|
if (*arg != '/') {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1649,7 +1647,7 @@ static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*arg) {
|
if (*arg) {
|
||||||
arg = (const char *)skipwhite(arg + 1);
|
arg = skipwhite(arg + 1);
|
||||||
|
|
||||||
// Check for trailing illegal characters.
|
// Check for trailing illegal characters.
|
||||||
if (*arg == NUL || strchr("|\"\n", *arg) == NULL) {
|
if (*arg == NUL || strchr("|\"\n", *arg) == NULL) {
|
||||||
@@ -1666,7 +1664,7 @@ static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg)
|
|||||||
static const char *set_context_in_unlet_cmd(expand_T *xp, const char *arg)
|
static const char *set_context_in_unlet_cmd(expand_T *xp, const char *arg)
|
||||||
{
|
{
|
||||||
while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) {
|
while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) {
|
||||||
arg = (const char *)xp->xp_pattern + 1;
|
arg = xp->xp_pattern + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
xp->xp_context = EXPAND_USER_VARS;
|
xp->xp_context = EXPAND_USER_VARS;
|
||||||
@@ -1683,7 +1681,7 @@ static const char *set_context_in_unlet_cmd(expand_T *xp, const char *arg)
|
|||||||
/// Set the completion context for the :language command. Always returns NULL.
|
/// Set the completion context for the :language command. Always returns NULL.
|
||||||
static const char *set_context_in_lang_cmd(expand_T *xp, const char *arg)
|
static const char *set_context_in_lang_cmd(expand_T *xp, const char *arg)
|
||||||
{
|
{
|
||||||
const char *p = (const char *)skiptowhite(arg);
|
const char *p = skiptowhite(arg);
|
||||||
if (*p == NUL) {
|
if (*p == NUL) {
|
||||||
xp->xp_context = EXPAND_LANGUAGE;
|
xp->xp_context = EXPAND_LANGUAGE;
|
||||||
xp->xp_pattern = (char *)arg;
|
xp->xp_pattern = (char *)arg;
|
||||||
@@ -1876,11 +1874,11 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
|||||||
case CMD_dsplit:
|
case CMD_dsplit:
|
||||||
return find_cmd_after_isearch_cmd(xp, arg);
|
return find_cmd_after_isearch_cmd(xp, arg);
|
||||||
case CMD_autocmd:
|
case CMD_autocmd:
|
||||||
return (const char *)set_context_in_autocmd(xp, (char *)arg, false);
|
return set_context_in_autocmd(xp, (char *)arg, false);
|
||||||
|
|
||||||
case CMD_doautocmd:
|
case CMD_doautocmd:
|
||||||
case CMD_doautoall:
|
case CMD_doautoall:
|
||||||
return (const char *)set_context_in_autocmd(xp, (char *)arg, true);
|
return set_context_in_autocmd(xp, (char *)arg, true);
|
||||||
case CMD_set:
|
case CMD_set:
|
||||||
set_context_in_set_cmd(xp, (char *)arg, 0);
|
set_context_in_set_cmd(xp, (char *)arg, 0);
|
||||||
break;
|
break;
|
||||||
@@ -1957,7 +1955,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
|||||||
case CMD_bwipeout:
|
case CMD_bwipeout:
|
||||||
case CMD_bunload:
|
case CMD_bunload:
|
||||||
while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) {
|
while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) {
|
||||||
arg = (const char *)xp->xp_pattern + 1;
|
arg = xp->xp_pattern + 1;
|
||||||
}
|
}
|
||||||
FALLTHROUGH;
|
FALLTHROUGH;
|
||||||
case CMD_buffer:
|
case CMD_buffer:
|
||||||
@@ -2063,7 +2061,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
|||||||
case CMD_tunmenu:
|
case CMD_tunmenu:
|
||||||
case CMD_popup:
|
case CMD_popup:
|
||||||
case CMD_emenu:
|
case CMD_emenu:
|
||||||
return (const char *)set_context_in_menu_cmd(xp, cmd, (char *)arg, forceit);
|
return set_context_in_menu_cmd(xp, cmd, (char *)arg, forceit);
|
||||||
|
|
||||||
case CMD_colorscheme:
|
case CMD_colorscheme:
|
||||||
xp->xp_context = EXPAND_COLORS;
|
xp->xp_context = EXPAND_COLORS;
|
||||||
@@ -2126,7 +2124,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
|||||||
|
|
||||||
case CMD_argdelete:
|
case CMD_argdelete:
|
||||||
while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL) {
|
while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL) {
|
||||||
arg = (const char *)(xp->xp_pattern + 1);
|
arg = (xp->xp_pattern + 1);
|
||||||
}
|
}
|
||||||
xp->xp_context = EXPAND_ARGLIST;
|
xp->xp_context = EXPAND_ARGLIST;
|
||||||
xp->xp_pattern = (char *)arg;
|
xp->xp_pattern = (char *)arg;
|
||||||
@@ -2186,7 +2184,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. skip over a range specifier of the form: addr [,addr] [;addr] ..
|
// 3. skip over a range specifier of the form: addr [,addr] [;addr] ..
|
||||||
cmd = (const char *)skip_range(cmd, &xp->xp_context);
|
cmd = skip_range(cmd, &xp->xp_context);
|
||||||
xp->xp_pattern = (char *)cmd;
|
xp->xp_pattern = (char *)cmd;
|
||||||
if (*cmd == NUL) {
|
if (*cmd == NUL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -2218,7 +2216,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
|||||||
ea.argt = excmd_get_argt(ea.cmdidx);
|
ea.argt = excmd_get_argt(ea.cmdidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *arg = (const char *)skipwhite(p);
|
const char *arg = skipwhite(p);
|
||||||
|
|
||||||
// Skip over ++argopt argument
|
// Skip over ++argopt argument
|
||||||
if ((ea.argt & EX_ARGOPT) && *arg != NUL && strncmp(arg, "++", 2) == 0) {
|
if ((ea.argt & EX_ARGOPT) && *arg != NUL && strncmp(arg, "++", 2) == 0) {
|
||||||
@@ -2226,7 +2224,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
|||||||
while (*p && !ascii_isspace(*p)) {
|
while (*p && !ascii_isspace(*p)) {
|
||||||
MB_PTR_ADV(p);
|
MB_PTR_ADV(p);
|
||||||
}
|
}
|
||||||
arg = (const char *)skipwhite(p);
|
arg = skipwhite(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
|
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
|
||||||
@@ -2234,7 +2232,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
|||||||
if (*++arg == '>') {
|
if (*++arg == '>') {
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
arg = (const char *)skipwhite(arg);
|
arg = skipwhite(arg);
|
||||||
} else if (*arg == '!' && ea.cmdidx == CMD_write) { // :w !filter
|
} else if (*arg == '!' && ea.cmdidx == CMD_write) { // :w !filter
|
||||||
arg++;
|
arg++;
|
||||||
usefilter = true;
|
usefilter = true;
|
||||||
@@ -2253,14 +2251,14 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
|||||||
while (*arg == *cmd) { // allow any number of '>' or '<'
|
while (*arg == *cmd) { // allow any number of '>' or '<'
|
||||||
arg++;
|
arg++;
|
||||||
}
|
}
|
||||||
arg = (const char *)skipwhite(arg);
|
arg = skipwhite(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does command allow "+command"?
|
// Does command allow "+command"?
|
||||||
if ((ea.argt & EX_CMDARG) && !usefilter && *arg == '+') {
|
if ((ea.argt & EX_CMDARG) && !usefilter && *arg == '+') {
|
||||||
// Check if we're in the +command
|
// Check if we're in the +command
|
||||||
p = arg + 1;
|
p = arg + 1;
|
||||||
arg = (const char *)skip_cmd_arg((char *)arg, false);
|
arg = skip_cmd_arg((char *)arg, false);
|
||||||
|
|
||||||
// Still touching the command after '+'?
|
// Still touching the command after '+'?
|
||||||
if (*arg == NUL) {
|
if (*arg == NUL) {
|
||||||
@@ -2268,7 +2266,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip space(s) after +command to get to the real argument.
|
// Skip space(s) after +command to get to the real argument.
|
||||||
arg = (const char *)skipwhite(arg);
|
arg = skipwhite(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for '|' to separate commands and '"' to start comments.
|
// Check for '|' to separate commands and '"' to start comments.
|
||||||
@@ -2344,7 +2342,7 @@ void set_cmd_context(expand_T *xp, char *str, int len, int col, int use_ccline)
|
|||||||
old_char = str[col];
|
old_char = str[col];
|
||||||
}
|
}
|
||||||
str[col] = NUL;
|
str[col] = NUL;
|
||||||
const char *nextcomm = (const char *)str;
|
const char *nextcomm = str;
|
||||||
|
|
||||||
if (use_ccline && ccline->cmdfirstc == '=') {
|
if (use_ccline && ccline->cmdfirstc == '=') {
|
||||||
// pass CMD_SIZE because there is no real command
|
// pass CMD_SIZE because there is no real command
|
||||||
@@ -2922,7 +2920,7 @@ static void expand_shellcmd_onedir(char *buf, char *s, size_t l, char *pat, char
|
|||||||
// Check if this name was already found.
|
// Check if this name was already found.
|
||||||
hash_T hash = hash_hash(name + l);
|
hash_T hash = hash_hash(name + l);
|
||||||
hashitem_T *hi =
|
hashitem_T *hi =
|
||||||
hash_lookup(ht, (const char *)(name + l), strlen(name + l), hash);
|
hash_lookup(ht, name + l, strlen(name + l), hash);
|
||||||
if (HASHITEM_EMPTY(hi)) {
|
if (HASHITEM_EMPTY(hi)) {
|
||||||
// Remove the path that was prepended.
|
// Remove the path that was prepended.
|
||||||
STRMOVE(name, name + l);
|
STRMOVE(name, name + l);
|
||||||
@@ -3166,7 +3164,7 @@ static int ExpandUserList(expand_T *xp, char ***matches, int *numMatches)
|
|||||||
continue; // Skip non-string items and empty strings.
|
continue; // Skip non-string items and empty strings.
|
||||||
}
|
}
|
||||||
|
|
||||||
GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
|
GA_APPEND(char *, &ga, xstrdup(TV_LIST_ITEM_TV(li)->vval.v_string));
|
||||||
});
|
});
|
||||||
tv_list_unref(retlist);
|
tv_list_unref(retlist);
|
||||||
|
|
||||||
@@ -3195,7 +3193,7 @@ static int ExpandUserLua(expand_T *xp, int *num_file, char ***file)
|
|||||||
continue; // Skip non-string items and empty strings.
|
continue; // Skip non-string items and empty strings.
|
||||||
}
|
}
|
||||||
|
|
||||||
GA_APPEND(char *, &ga, xstrdup((const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
|
GA_APPEND(char *, &ga, xstrdup(TV_LIST_ITEM_TV(li)->vval.v_string));
|
||||||
});
|
});
|
||||||
tv_list_unref(retlist);
|
tv_list_unref(retlist);
|
||||||
|
|
||||||
@@ -3479,7 +3477,6 @@ void wildmenu_cleanup(CmdlineInfo *cclp)
|
|||||||
/// "getcompletion()" function
|
/// "getcompletion()" function
|
||||||
void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||||
{
|
{
|
||||||
char *pat;
|
|
||||||
expand_T xpc;
|
expand_T xpc;
|
||||||
bool filtered = false;
|
bool filtered = false;
|
||||||
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
|
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
|
||||||
@@ -3511,9 +3508,10 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
const char *pattern = tv_get_string(&argvars[0]);
|
const char *pattern = tv_get_string(&argvars[0]);
|
||||||
|
|
||||||
if (strcmp(type, "cmdline") == 0) {
|
if (strcmp(type, "cmdline") == 0) {
|
||||||
set_one_cmd_context(&xpc, pattern);
|
const int cmdline_len = (int)strlen(pattern);
|
||||||
|
set_cmd_context(&xpc, (char *)pattern, cmdline_len, cmdline_len, false);
|
||||||
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
|
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
|
||||||
xpc.xp_col = (int)strlen(pattern);
|
xpc.xp_col = cmdline_len;
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3540,6 +3538,8 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
|
;
|
||||||
|
char *pat;
|
||||||
if (cmdline_fuzzy_completion_supported(&xpc)) {
|
if (cmdline_fuzzy_completion_supported(&xpc)) {
|
||||||
// when fuzzy matching, don't modify the search string
|
// when fuzzy matching, don't modify the search string
|
||||||
pat = xstrdup(xpc.xp_pattern);
|
pat = xstrdup(xpc.xp_pattern);
|
||||||
@@ -3551,8 +3551,7 @@ theend:
|
|||||||
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
|
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
|
||||||
|
|
||||||
for (int i = 0; i < xpc.xp_numfiles; i++) {
|
for (int i = 0; i < xpc.xp_numfiles; i++) {
|
||||||
tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i],
|
tv_list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
|
||||||
-1);
|
|
||||||
}
|
}
|
||||||
xfree(pat);
|
xfree(pat);
|
||||||
ExpandCleanup(&xpc);
|
ExpandCleanup(&xpc);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user