mirror of
https://github.com/neovim/neovim
synced 2025-07-21 22:02:16 +00:00
Compare commits
409 Commits
Author | SHA1 | Date | |
---|---|---|---|
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
|
||||
timeout_in: 30m
|
||||
install_script:
|
||||
- pkg update -f
|
||||
- pkg install -y cmake gmake ninja pkgconf unzip wget gettext python libffi git
|
||||
build_deps_script:
|
||||
- gmake deps
|
||||
build_script:
|
||||
- gmake nvim
|
||||
- gmake CMAKE_EXTRA_FLAGS="-DCI_BUILD=ON" nvim
|
||||
workaround_script:
|
||||
# Run tests as user "cirrus" instead of root. This is required for the
|
||||
# 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
|
||||
shell: bash
|
||||
|
||||
- id: image
|
||||
run: echo "version=$ImageVersion" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
# Avoid using '**/CMakeLists.txt' (or any pattern starting with '**/') even
|
||||
# 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
|
||||
@ -17,6 +21,6 @@ runs:
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
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',
|
||||
'runtime/CMakeLists.txt', 'src/nvim/**/CMakeLists.txt') }}
|
||||
|
8
.github/scripts/build_universal_macos.sh
vendored
8
.github/scripts/build_universal_macos.sh
vendored
@ -25,12 +25,10 @@ MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -f1 -d.)"
|
||||
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 --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 --install build --prefix build/release/nvim-macos
|
||||
cd build
|
||||
# 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
|
||||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
10
.github/scripts/remove-reviewers.js
vendored
10
.github/scripts/remove-reviewers.js
vendored
@ -1,18 +1,16 @@
|
||||
module.exports = async ({github, context}) => {
|
||||
module.exports = async ({ github, context }) => {
|
||||
const requestedReviewers = await github.rest.pulls.listRequestedReviewers({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number
|
||||
pull_number: context.issue.number,
|
||||
});
|
||||
|
||||
const reviewers = requestedReviewers.data.users.map(e => e.login)
|
||||
const team_reviewers = requestedReviewers.data.teams.map(e => e.name);
|
||||
const reviewers = requestedReviewers.data.users.map((e) => e.login);
|
||||
|
||||
github.rest.pulls.removeRequestedReviewers({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number,
|
||||
reviewers: reviewers,
|
||||
team_reviewers: team_reviewers
|
||||
});
|
||||
}
|
||||
};
|
||||
|
116
.github/scripts/reviews.js
vendored
116
.github/scripts/reviews.js
vendored
@ -1,102 +1,114 @@
|
||||
module.exports = async ({github, context}) => {
|
||||
module.exports = async ({ github, context }) => {
|
||||
const pr_data = await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number
|
||||
})
|
||||
const labels = pr_data.data.labels.map(e => e.name)
|
||||
pull_number: context.issue.number,
|
||||
});
|
||||
const labels = pr_data.data.labels.map((e) => e.name);
|
||||
const reviewers = new Set();
|
||||
|
||||
const reviewers = new Set()
|
||||
const team_reviewers = new Array()
|
||||
if (labels.includes('api')) {
|
||||
reviewers.add("bfredl")
|
||||
if (labels.includes("api")) {
|
||||
reviewers.add("bfredl");
|
||||
reviewers.add("famiu");
|
||||
}
|
||||
|
||||
if (labels.includes('build')) {
|
||||
team_reviewers.push('ci');
|
||||
if (labels.includes("build")) {
|
||||
reviewers.add("dundargoc");
|
||||
reviewers.add("jamessan");
|
||||
reviewers.add("justinmk");
|
||||
}
|
||||
|
||||
if (labels.includes('ci')) {
|
||||
team_reviewers.push('ci');
|
||||
if (labels.includes("ci")) {
|
||||
reviewers.add("dundargoc");
|
||||
reviewers.add("jamessan");
|
||||
reviewers.add("justinmk");
|
||||
}
|
||||
|
||||
if (labels.includes('column')) {
|
||||
reviewers.add("lewis6991")
|
||||
if (labels.includes("column")) {
|
||||
reviewers.add("lewis6991");
|
||||
}
|
||||
|
||||
if (labels.includes('dependencies')) {
|
||||
reviewers.add("jamessan")
|
||||
if (labels.includes("dependencies")) {
|
||||
reviewers.add("jamessan");
|
||||
}
|
||||
|
||||
if (labels.includes('diagnostic')) {
|
||||
reviewers.add("gpanders")
|
||||
if (labels.includes("diagnostic")) {
|
||||
reviewers.add("gpanders");
|
||||
}
|
||||
|
||||
if (labels.includes('diff')) {
|
||||
reviewers.add("lewis6991")
|
||||
if (labels.includes("diff")) {
|
||||
reviewers.add("lewis6991");
|
||||
}
|
||||
|
||||
if (labels.includes('distribution')) {
|
||||
reviewers.add("jamessan")
|
||||
if (labels.includes("distribution")) {
|
||||
reviewers.add("jamessan");
|
||||
}
|
||||
|
||||
if (labels.includes('documentation')) {
|
||||
reviewers.add("clason")
|
||||
if (labels.includes("documentation")) {
|
||||
reviewers.add("clason");
|
||||
}
|
||||
|
||||
if (labels.includes('extmarks')) {
|
||||
reviewers.add("bfredl")
|
||||
if (labels.includes("extmarks")) {
|
||||
reviewers.add("bfredl");
|
||||
}
|
||||
|
||||
if (labels.includes('filetype')) {
|
||||
reviewers.add("clason")
|
||||
reviewers.add("gpanders")
|
||||
reviewers.add("smjonas")
|
||||
if (labels.includes("filetype")) {
|
||||
reviewers.add("clason");
|
||||
reviewers.add("gpanders");
|
||||
reviewers.add("smjonas");
|
||||
}
|
||||
|
||||
if (labels.includes('lsp')) {
|
||||
team_reviewers.push('lsp');
|
||||
if (labels.includes("lsp")) {
|
||||
reviewers.add("folke");
|
||||
reviewers.add("glepnir");
|
||||
reviewers.add("mfussenegger");
|
||||
}
|
||||
|
||||
if (labels.includes('platform:nix')) {
|
||||
reviewers.add("teto")
|
||||
if (labels.includes("platform:nix")) {
|
||||
reviewers.add("teto");
|
||||
}
|
||||
|
||||
if (labels.includes('project-management')) {
|
||||
reviewers.add("bfredl")
|
||||
reviewers.add("justinmk")
|
||||
if (labels.includes("project-management")) {
|
||||
reviewers.add("bfredl");
|
||||
reviewers.add("justinmk");
|
||||
}
|
||||
|
||||
if (labels.includes('test')) {
|
||||
reviewers.add("justinmk")
|
||||
if (labels.includes("statusline")) {
|
||||
reviewers.add("famiu");
|
||||
}
|
||||
|
||||
if (labels.includes('treesitter')) {
|
||||
team_reviewers.push('treesitter');
|
||||
if (labels.includes("test")) {
|
||||
reviewers.add("justinmk");
|
||||
}
|
||||
|
||||
if (labels.includes('typo')) {
|
||||
reviewers.add("dundargoc")
|
||||
if (labels.includes("treesitter")) {
|
||||
reviewers.add("bfredl");
|
||||
reviewers.add("clason");
|
||||
reviewers.add("lewis6991");
|
||||
}
|
||||
|
||||
if (labels.includes('ui')) {
|
||||
reviewers.add("bfredl")
|
||||
if (labels.includes("typo")) {
|
||||
reviewers.add("dundargoc");
|
||||
}
|
||||
|
||||
if (labels.includes('vim-patch')) {
|
||||
reviewers.add("seandewar")
|
||||
reviewers.add("zeertzjq")
|
||||
if (labels.includes("ui")) {
|
||||
reviewers.add("bfredl");
|
||||
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
|
||||
const pr_opener = pr_data.data.user.login
|
||||
reviewers.delete(pr_opener)
|
||||
const pr_opener = pr_data.data.user.login;
|
||||
reviewers.delete(pr_opener);
|
||||
|
||||
github.rest.pulls.requestReviewers({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number,
|
||||
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'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.TEAM_REVIEW }}
|
||||
script: |
|
||||
const script = require('./.github/scripts/reviews.js')
|
||||
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
|
||||
# Also work as a check for PR's to not forget committing their doc changes
|
||||
# called from api-docs-check.yml
|
||||
# Check if any PR needs to run the autogenerate script
|
||||
name: Autogenerate API docs
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/nvim/api/*.[ch]'
|
||||
- 'runtime/lua/**.lua'
|
||||
- 'runtime/doc/**'
|
||||
branches:
|
||||
- 'master'
|
||||
- 'release-[0-9]+.[0-9]+'
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs:
|
||||
check_only:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
regen-api-docs:
|
||||
@ -25,50 +13,26 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: rhysd/action-setup-vim@v1
|
||||
with:
|
||||
neovim: true
|
||||
version: nightly
|
||||
- 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
|
||||
run: |
|
||||
sudo apt-get update
|
||||
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
|
||||
id: docs
|
||||
run: |
|
||||
git checkout -b ${DOC_BRANCH}
|
||||
python3 scripts/gen_vimdoc.py
|
||||
printf 'UPDATED_DOCS=%s\n' $([ -z "$(git diff)" ]; echo $?) >> $GITHUB_OUTPUT
|
||||
|
||||
- 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: |
|
||||
echo "Job failed, run ./scripts/gen_vimdoc.py and commit your doc changes"
|
||||
echo "The doc generation produces the following changes:"
|
||||
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
|
||||
pull-requests: write
|
||||
name: Backport Pull Request
|
||||
if: >
|
||||
github.repository_owner == 'neovim' && (
|
||||
github.event_name == 'pull_request_target' &&
|
||||
github.event.pull_request.merged
|
||||
)
|
||||
if: github.event.pull_request.merged
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
- name: Create backport PRs
|
||||
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
|
||||
|
||||
- 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
|
||||
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:
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
sync-labels: ""
|
||||
|
||||
type-scope:
|
||||
@ -44,7 +43,6 @@ jobs:
|
||||
- name: 'Request reviewers'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.TEAM_REVIEW }}
|
||||
script: |
|
||||
const script = require('./.github/scripts/reviews.js')
|
||||
await script({github, context})
|
||||
|
2
.github/workflows/lintcommit.yml
vendored
2
.github/workflows/lintcommit.yml
vendored
@ -8,8 +8,6 @@ jobs:
|
||||
lint-commits:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.draft == false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
|
6
.github/workflows/notes.md
vendored
6
.github/workflows/notes.md
vendored
@ -9,14 +9,14 @@ ${NVIM_VERSION}
|
||||
#### Zip
|
||||
|
||||
1. Download **nvim-win64.zip**
|
||||
2. Extract the zip.
|
||||
2. Extract the zip
|
||||
3. Run `nvim-qt.exe`
|
||||
|
||||
#### MSI
|
||||
|
||||
1. Download **nvim-win64.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
|
||||
|
||||
@ -38,8 +38,6 @@ ${NVIM_VERSION}
|
||||
|
||||
#### Tarball
|
||||
|
||||
*(deprecated)*
|
||||
|
||||
1. Download **nvim-linux64.tar.gz**
|
||||
2. Extract: `tar xzvf nvim-linux64.tar.gz`
|
||||
3. Run `./nvim-linux64/bin/nvim`
|
||||
|
63
.github/workflows/release.yml
vendored
63
.github/workflows/release.yml
vendored
@ -17,39 +17,10 @@ on:
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
CC: gcc-10
|
||||
outputs:
|
||||
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:
|
||||
image: ubuntu:18.04
|
||||
options: --privileged # Privileged mode is needed to load fuse module.
|
||||
@ -71,11 +42,19 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
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')
|
||||
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')
|
||||
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
|
||||
with:
|
||||
name: appimage
|
||||
@ -83,6 +62,18 @@ jobs:
|
||||
build/bin/nvim.appimage
|
||||
build/bin/nvim.appimage.zsync
|
||||
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:
|
||||
runs-on: macos-11
|
||||
@ -126,7 +117,7 @@ jobs:
|
||||
cmake --build .deps
|
||||
- name: build package
|
||||
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
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@ -137,7 +128,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
publish:
|
||||
needs: [linux, appimage, macOS, windows]
|
||||
needs: [linux, macOS, windows]
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
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'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.TEAM_REVIEW }}
|
||||
script: |
|
||||
const script = require('./.github/scripts/remove-reviewers.js')
|
||||
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
|
||||
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
|
||||
id: cache-uncrustify
|
||||
uses: actions/cache@v3
|
||||
@ -76,7 +83,7 @@ jobs:
|
||||
|
||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||
name: configure
|
||||
run: cmake -B build -G Ninja -D CI_BUILD=OFF
|
||||
run: cmake -B build -G Ninja
|
||||
|
||||
- if: "!cancelled()"
|
||||
name: Determine if run should be aborted
|
||||
@ -84,12 +91,8 @@ jobs:
|
||||
run: echo "status=${{ job.status }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||
name: lintstylua
|
||||
uses: JohnnyMorganz/stylua-action@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
version: latest
|
||||
args: --check runtime/
|
||||
name: stylua
|
||||
run: cmake --build build --target lintlua-stylua
|
||||
|
||||
- if: success() || failure() && steps.abort_job.outputs.status == 'success'
|
||||
name: luacheck
|
||||
@ -111,18 +114,6 @@ jobs:
|
||||
run: |
|
||||
${{ 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:
|
||||
name: ${{ matrix.runner }} ${{ matrix.flavor }} (cc=${{ matrix.cc }})
|
||||
strategy:
|
||||
@ -197,7 +188,7 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
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
|
||||
|
||||
- if: "!cancelled()"
|
||||
@ -276,7 +267,7 @@ jobs:
|
||||
cmake --build .deps
|
||||
|
||||
- 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
|
||||
run: cmake --build build --config Release
|
||||
@ -313,7 +304,7 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
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
|
||||
|
||||
- name: Install test deps
|
||||
@ -405,5 +396,5 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B build -G Ninja
|
||||
cmake -B build -G Ninja -D CI_BUILD=ON
|
||||
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})
|
||||
endif()
|
||||
|
||||
if(NOT CI_BUILD)
|
||||
set(CMAKE_INSTALL_MESSAGE NEVER)
|
||||
endif()
|
||||
|
||||
# Prefer our bundled versions of dependencies.
|
||||
if(DEFINED ENV{DEPS_BUILD_DIR})
|
||||
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`.
|
||||
set(NVIM_VERSION_MAJOR 0)
|
||||
set(NVIM_VERSION_MINOR 9)
|
||||
set(NVIM_VERSION_PATCH 0)
|
||||
set(NVIM_VERSION_PATCH 2)
|
||||
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
|
||||
|
||||
# API level
|
||||
@ -246,6 +250,8 @@ add_glob_target(
|
||||
FLAGS --color=always --check
|
||||
GLOB_DIRS runtime/
|
||||
GLOB_PAT *.lua
|
||||
EXCLUDE
|
||||
/runtime/lua/vim/re.lua
|
||||
TOUCH_STRATEGY SINGLE)
|
||||
|
||||
add_custom_target(lintlua)
|
||||
|
@ -132,15 +132,15 @@ endif()
|
||||
include(ExternalProject)
|
||||
set_directory_properties(PROPERTIES EP_PREFIX "${DEPS_BUILD_DIR}")
|
||||
|
||||
set(LIBUV_URL https://github.com/libuv/libuv/archive/62c2374a8c005ce9e42088965f8f8af2532c177b.tar.gz)
|
||||
set(LIBUV_SHA256 c7e89137da65a1cb550ba96b892dfeeabea982bf33b9237bcf9bbcd90f2e70a1)
|
||||
set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.46.0.tar.gz)
|
||||
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_SHA256 3654f5e2c652dc52e0a993e270bb57d5702b262703f03771c152bba51602aeba)
|
||||
|
||||
# https://github.com/LuaJIT/LuaJIT/tree/v2.1
|
||||
set(LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/505e2c03de35e2718eef0d2d3660712e06dadf1f.tar.gz)
|
||||
set(LUAJIT_SHA256 67c88399b901a22e9a236f4b77e6fe39af00f6b7144ce9dd6f51141d921f1076)
|
||||
set(LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/03c31124cc3b521ef54fe398e10fa55660a5057d.tar.gz)
|
||||
set(LUAJIT_SHA256 61dcc7ae3f543ae3cc30e66db060e31e2a77e4be34ee65e370c953d112b4d60c)
|
||||
|
||||
set(LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz)
|
||||
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_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(LIBVTERM_URL https://launchpad.net/libvterm/trunk/v0.3/+download/libvterm-0.3.1.tar.gz)
|
||||
set(LIBVTERM_SHA256 25a8ad9c15485368dfd0a8a9dca1aec8fea5c27da3fa74ec518d5d3787f0c397)
|
||||
set(LIBVTERM_URL https://github.com/neovim/deps/raw/12c9dcf1d823ac4acbccf494c93c4774a87db11d/opt/libvterm-0.3.3.tar.gz)
|
||||
set(LIBVTERM_SHA256 09156f43dd2128bd347cbeebe50d9a571d32c64e0cf18d211197946aff7226e0)
|
||||
|
||||
set(LUV_URL https://github.com/luvit/luv/archive/093a977b82077591baefe1e880d37dfa2730bd54.tar.gz)
|
||||
set(LUV_SHA256 222b38b6425f0926218e14e7da81481fdde6f9660c1feac25a53e6fb52e886e6)
|
||||
set(LUV_URL https://github.com/luvit/luv/archive/1.45.0-0.tar.gz)
|
||||
set(LUV_SHA256 97e89940f9eeaa8dfb34f1c19f80dd373299c42719d15228ec790f415d4e4965)
|
||||
|
||||
set(LUA_COMPAT53_URL https://github.com/keplerproject/lua-compat-5.3/archive/v0.9.tar.gz)
|
||||
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_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178)
|
||||
|
||||
set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.20.2.tar.gz)
|
||||
set(TREESITTER_C_SHA256 af66fde03feb0df4faf03750102a0d265b007e5d957057b6b293c13116a70af2 )
|
||||
set(TREESITTER_LUA_URL https://github.com/MunifTanjim/tree-sitter-lua/archive/v0.0.14.tar.gz)
|
||||
set(TREESITTER_LUA_SHA256 930d0370dc15b66389869355c8e14305b9ba7aafd36edbfdb468c8023395016d)
|
||||
set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.20.5.tar.gz)
|
||||
set(TREESITTER_C_SHA256 694a5408246ee45d535df9df025febecdb50bee764df64a94346b9805a5f349b )
|
||||
set(TREESITTER_LUA_URL https://github.com/MunifTanjim/tree-sitter-lua/archive/v0.0.18.tar.gz)
|
||||
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_SHA256 403acec3efb7cdb18ff3d68640fc823502a4ffcdfbb71cec3f98aa786c21cbe2)
|
||||
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}"
|
||||
INSTALL_COMMAND "${_luajit_INSTALL_COMMAND}"
|
||||
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()
|
||||
|
||||
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 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} -E make_directory ${DEPS_BIN_DIR}/lua/jit
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${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
|
||||
)
|
||||
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 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} -E make_directory ${DEPS_BIN_DIR}/lua/jit
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_BUILD_DIR}/src/luajit/src/jit ${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
|
||||
)
|
||||
else()
|
||||
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_VENDOR "neovim.io")
|
||||
set(CPACK_PACKAGE_FILE_NAME "nvim")
|
||||
set(CPACK_PACKAGE_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
# From the GitHub About section
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Vim-fork focused on extensibility and usability.")
|
||||
|
@ -11,11 +11,4 @@
|
||||
Value='[INSTALL_ROOT]bin'
|
||||
/>
|
||||
</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>
|
||||
|
@ -25,7 +25,8 @@ function! s:selection.on_exit(jobid, data, event) abort
|
||||
if self.owner == a:jobid
|
||||
let self.owner = 0
|
||||
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
|
||||
echomsg 'clipboard: error invoking '.get(self.argv, 0, '?').': '.join(self.stderr)
|
||||
echohl None
|
||||
|
@ -120,6 +120,8 @@ LSP FUNCTIONS
|
||||
{buffer = bufnr} instead.
|
||||
- *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
|
||||
{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()|
|
||||
or |vim.lsp.buf.format()| instead.
|
||||
|
||||
|
@ -295,6 +295,14 @@ DiagnosticSignHint
|
||||
DiagnosticSignOk
|
||||
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*
|
||||
|
||||
|
@ -83,14 +83,14 @@ For the most recent information about sponsoring look on the Vim web site:
|
||||
https://www.vim.org/sponsor/
|
||||
|
||||
|
||||
Neovim development is funded separately from Vim:
|
||||
Nvim development is funded separately from Vim:
|
||||
|
||||
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:
|
||||
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/
|
||||
|
||||
==============================================================================
|
||||
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*
|
||||
|
||||
@ -372,6 +385,7 @@ notation meaning equivalent decimal value(s) ~
|
||||
<C-…> control-key *control* *ctrl* *<C-*
|
||||
<M-…> alt-key or meta-key *META* *ALT* *<M-*
|
||||
<A-…> same as <M-…> *<A-*
|
||||
<T-…> meta-key when it's not alt *<T-*
|
||||
<D-…> command-key or "super" key *<D-*
|
||||
----------------------------------------------------------------------- ~
|
||||
|
||||
@ -385,7 +399,7 @@ Note:
|
||||
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
|
||||
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|
|
||||
|
||||
*<>*
|
||||
|
@ -974,8 +974,7 @@ start_client({config}) *vim.lsp.start_client()*
|
||||
passed to the language server on initialization. Hint: use
|
||||
make_client_capabilities() and modify its result.
|
||||
• Note: To send an empty dictionary use
|
||||
`{[vim.type_idx]=vim.types.dictionary}`, else it will be
|
||||
encoded as an array.
|
||||
|vim.empty_dict()|, else it will be encoded as an array.
|
||||
|
||||
• handlers: Map of language server method names to
|
||||
|lsp-handler|
|
||||
@ -2130,27 +2129,6 @@ start({cmd}, {cmd_args}, {dispatchers}, {extra_spawn_params})
|
||||
• `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*
|
||||
|
||||
|
@ -318,6 +318,6 @@ release.
|
||||
|
||||
• |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:
|
||||
|
@ -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)
|
||||
global
|
||||
When on, the OS function fsync() will be called after saving a file
|
||||
(|:write|, |writefile()|, …), |swap-file| and |shada-file|. This
|
||||
flushes the file to disk, ensuring that it is safely written.
|
||||
(|:write|, |writefile()|, …), |swap-file|, |undo-persistence| and |shada-file|.
|
||||
This flushes the file to disk, ensuring that it is safely written.
|
||||
Slow on some systems: writing buffers, quitting Nvim, and other
|
||||
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|
|
||||
commands. It must end in ".{encoding}.add". You need to include the
|
||||
path, otherwise the file is placed in the current directory.
|
||||
The path may include characters from 'isfname', space, comma and '@'.
|
||||
*E765*
|
||||
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
|
||||
|
@ -1120,21 +1120,24 @@ LanguageTree:parse({self}) *LanguageTree:parse()*
|
||||
Return: ~
|
||||
TSTree[]
|
||||
|
||||
LanguageTree:register_cbs({self}, {cbs}) *LanguageTree:register_cbs()*
|
||||
*LanguageTree:register_cbs()*
|
||||
LanguageTree:register_cbs({self}, {cbs}, {recursive})
|
||||
Registers callbacks for the |LanguageTree|.
|
||||
|
||||
Parameters: ~
|
||||
• {cbs} (table) An |nvim_buf_attach()|-like table argument with the
|
||||
following handlers:
|
||||
• `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
|
||||
the tree has syntactical changes. It will only be passed one
|
||||
argument, which is a table of the ranges (as node ranges)
|
||||
that changed.
|
||||
• `on_child_added` : emitted when a child is added to the
|
||||
tree.
|
||||
• `on_child_removed` : emitted when a child is removed from
|
||||
the tree.
|
||||
• {cbs} (table) An |nvim_buf_attach()|-like table argument with
|
||||
the following handlers:
|
||||
• `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 the tree has syntactical changes. It will
|
||||
only be passed one argument, which is a table of the
|
||||
ranges (as node ranges) that changed.
|
||||
• `on_child_added` : emitted when a child is added to
|
||||
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}
|
||||
|
||||
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_line',
|
||||
[2, 0, 0, [[' ' , 0, 77]]],
|
||||
[2, 1, 0, [['~', 7], [' ', 7, 76]]],
|
||||
[2, 9, 0, [['~', 7], [' ', 7, 76]]],
|
||||
[2, 0, 0, [[' ' , 0, 77]], false],
|
||||
[2, 1, 0, [['~', 7], [' ', 7, 76]], false],
|
||||
[2, 9, 0, [['~', 7], [' ', 7, 76]], false],
|
||||
...
|
||||
[2, 35, 0, [['~', 7], [' ', 7, 76]]],
|
||||
[1, 36, 0, [['[', 9], ['N'], ['o'], [' '], ['N'], ['a'], ['m'], ['e'], [']']]],
|
||||
[1, 36, 9, [[' ', 9, 50]]],
|
||||
[1, 36, 59, [['0', 9], [','], ['0'], ['-' ], ['1'], [' ', 9, 10], ['A'], ['l', 9, 2]]]
|
||||
[2, 35, 0, [['~', 7], [' ', 7, 76]], false],
|
||||
[1, 36, 0, [['[', 9], ['N'], ['o'], [' '], ['N'], ['a'], ['m'], ['e'], [']']], false],
|
||||
[1, 36, 9, [[' ', 9, 50]], false],
|
||||
[1, 36, 59, [['0', 9], [','], ['0'], ['-' ], ['1'], [' ', 9, 10], ['A'], ['l', 9, 2]], false]
|
||||
],
|
||||
['msg_showmode', [[]]],
|
||||
['win_pos', [2, 1000, 0, 0, 77, 36]],
|
||||
@ -199,7 +199,7 @@ the editor.
|
||||
The following keys are deprecated:
|
||||
|
||||
`hl_id`: Use `attr_id` instead.
|
||||
`hl_lm`: Use `attr_id_lm` instead.
|
||||
`id_lm`: Use `attr_id_lm` instead.
|
||||
|
||||
["option_set", name, value] ~
|
||||
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
|
||||
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`
|
||||
attributes.
|
||||
|
||||
@ -352,7 +352,7 @@ numerical highlight ids to the actual attributes.
|
||||
|ui-hlstate| extension explained below.
|
||||
|
||||
["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
|
||||
to render the grids which use attribute ids directly, but is useful
|
||||
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.
|
||||
|
||||
*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
|
||||
`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
|
||||
@ -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
|
||||
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] ~
|
||||
Clear a `grid`.
|
||||
|
||||
@ -428,7 +434,7 @@ numerical highlight ids to the actual attributes.
|
||||
+-------------------------+
|
||||
<
|
||||
`cols` is always zero in this version of Nvim, and reserved for future
|
||||
use.
|
||||
use.
|
||||
|
||||
Note when updating code from |ui-grid-old| events: ranges are
|
||||
end-exclusive, which is consistent with API conventions, but different
|
||||
@ -634,11 +640,19 @@ tabs.
|
||||
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
|
||||
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] ~
|
||||
Updates the position of an extmark which is currently visible in a
|
||||
window. Only emitted if the mark has the `ui_watched` attribute.
|
||||
window. Only emitted if the mark has the `ui_watched` attribute.
|
||||
|
||||
==============================================================================
|
||||
Popupmenu Events *ui-popupmenu*
|
||||
@ -710,7 +724,7 @@ For command-line 'wildmenu' UI events, activate |ui-popupmenu|.
|
||||
to distinguish different command lines active at the same time. The
|
||||
first invoked command line has level 1, the next recursively-invoked
|
||||
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] ~
|
||||
Change the cursor position in the cmdline.
|
||||
|
@ -8,6 +8,9 @@ vim.api.nvim_create_augroup('filetypedetect', { clear = false })
|
||||
vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
|
||||
group = 'filetypedetect',
|
||||
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 })
|
||||
if not ft then
|
||||
-- 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
|
||||
" "aaa.bbb" load "aaa" and then "bbb".
|
||||
for name in split(s, '\.')
|
||||
exe 'runtime! ftplugin/' . name . '.vim ftplugin/' . name . '_*.vim ftplugin/' . name . '/*.vim'
|
||||
" Load lua ftplugins
|
||||
exe printf('runtime! ftplugin/%s.lua ftplugin/%s_*.lua ftplugin/%s/*.lua', name, name, name)
|
||||
" Load Lua ftplugins after Vim ftplugins _per directory_
|
||||
" TODO(clason): use nvim__get_runtime when supports globs and modeline
|
||||
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
|
||||
endif
|
||||
endfunc
|
||||
|
1
runtime/ftplugin/cs.lua
Normal file
1
runtime/ftplugin/cs.lua
Normal file
@ -0,0 +1 @@
|
||||
vim.bo.commentstring = '/*%s*/'
|
@ -1,5 +1,6 @@
|
||||
local M = {}
|
||||
|
||||
--- @type table<string,fun(bufnr: integer, val: string, opts?: table)>
|
||||
M.properties = {}
|
||||
|
||||
--- Modified version of the builtin assert that does not include error position information
|
||||
@ -19,7 +20,7 @@ end
|
||||
---
|
||||
---@private
|
||||
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',
|
||||
})
|
||||
end
|
||||
@ -111,7 +112,20 @@ end
|
||||
function M.properties.insert_final_newline(bufnr, val)
|
||||
assert(val == 'true' or val == 'false', 'insert_final_newline must be either "true" or "false"')
|
||||
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
|
||||
|
||||
--- 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 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
|
||||
local function parse(filepath, dir)
|
||||
local pat = nil
|
||||
local opts = {}
|
||||
local pat --- @type vim.regex?
|
||||
local opts = {} --- @type table<string,string|boolean>
|
||||
local f = io.open(dir .. '/.editorconfig')
|
||||
if f then
|
||||
for line in f:lines() do
|
||||
@ -189,6 +203,7 @@ local function parse(filepath, dir)
|
||||
end
|
||||
elseif key ~= nil and val ~= nil then
|
||||
if key == 'root' then
|
||||
assert(val == 'true' or val == 'false', 'root must be either "true" or "false"')
|
||||
opts.root = val == 'true'
|
||||
elseif pat and pat:match_str(filepath) then
|
||||
opts[key] = val
|
||||
@ -207,12 +222,16 @@ end
|
||||
---@private
|
||||
function M.config(bufnr)
|
||||
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))
|
||||
if vim.bo[bufnr].buftype ~= '' or not vim.bo[bufnr].modifiable or path == '' then
|
||||
return
|
||||
end
|
||||
|
||||
local opts = {}
|
||||
local opts = {} --- @type table<string,string|boolean>
|
||||
for parent in vim.fs.parents(path) do
|
||||
for k, v in pairs(parse(path, parent)) do
|
||||
if opts[k] == nil then
|
||||
@ -225,7 +244,7 @@ function M.config(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
local applied = {}
|
||||
local applied = {} --- @type table<string,string|boolean>
|
||||
for opt, val in pairs(opts) do
|
||||
if val ~= 'unset' then
|
||||
local func = M.properties[opt]
|
||||
|
@ -64,6 +64,7 @@ local function system(cmd_, silent, env)
|
||||
local cmd_str = table.concat(cmd, ' ')
|
||||
man_error(string.format('command error: %s', cmd_str))
|
||||
end
|
||||
return ''
|
||||
end
|
||||
|
||||
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 }), ',')
|
||||
---@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.
|
||||
local first = M.find_path(sect, name)
|
||||
@ -738,7 +739,12 @@ function M.open_page(count, smods, args)
|
||||
else
|
||||
-- Combine the name and sect into a manpage reference so that all
|
||||
-- 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]
|
||||
table.remove(args, 1)
|
||||
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-silent'
|
||||
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
|
||||
f_tab = true
|
||||
f_silent = true
|
||||
@ -847,14 +847,14 @@ function vim._cs_remote(rcid, server_addr, connect_error, args)
|
||||
if rcid == 0 then
|
||||
return { errmsg = connection_failure_errmsg('Send failed.') }
|
||||
end
|
||||
vim.fn.rpcrequest(rcid, 'nvim_input', args[2])
|
||||
vim.rpcrequest(rcid, 'nvim_input', args[2])
|
||||
return { should_exit = true, tabbed = false }
|
||||
elseif subcmd == 'expr' then
|
||||
if rcid == 0 then
|
||||
return { errmsg = connection_failure_errmsg('Send expression failed.') }
|
||||
end
|
||||
print(vim.fn.rpcrequest(rcid, 'nvim_eval', args[2]))
|
||||
return { should_exit = true, tabbed = false }
|
||||
local res = tostring(vim.rpcrequest(rcid, 'nvim_eval', args[2]))
|
||||
return { result = res, should_exit = true, tabbed = false }
|
||||
elseif subcmd ~= '' then
|
||||
return { errmsg = 'Unknown option argument: ' .. args[1] }
|
||||
end
|
||||
|
@ -70,15 +70,18 @@ function vim.inspect_pos(bufnr, row, col, filter)
|
||||
if filter.treesitter then
|
||||
for _, capture in pairs(vim.treesitter.get_captures_at_pos(bufnr, row, col)) do
|
||||
capture.hl_group = '@' .. capture.capture .. '.' .. capture.lang
|
||||
table.insert(results.treesitter, resolve_hl(capture))
|
||||
results.treesitter[#results.treesitter + 1] = resolve_hl(capture)
|
||||
end
|
||||
end
|
||||
|
||||
-- syntax
|
||||
if filter.syntax then
|
||||
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') }))
|
||||
end
|
||||
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
|
||||
results.syntax[#results.syntax + 1] =
|
||||
resolve_hl({ hl_group = vim.fn.synIDattr(i1, 'name') })
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- namespace id -> name map
|
||||
|
@ -88,6 +88,9 @@ local default_poll_interval_ms = 2000
|
||||
--- be invoked recursively)
|
||||
--- - children (table|nil)
|
||||
--- 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)
|
||||
path = vim.fs.normalize(path)
|
||||
local interval = opts and opts.interval or default_poll_interval_ms
|
||||
@ -112,7 +115,9 @@ local function poll_internal(path, opts, callback, watches)
|
||||
end)
|
||||
)
|
||||
assert(not start_err, start_err)
|
||||
callback(path, M.FileChangeType.Created)
|
||||
if watches.started then
|
||||
callback(path, M.FileChangeType.Created)
|
||||
end
|
||||
end
|
||||
|
||||
watches.cancel = function()
|
||||
@ -132,6 +137,7 @@ local function poll_internal(path, opts, callback, watches)
|
||||
if not watches.children[name] then
|
||||
watches.children[name] = {
|
||||
is_dir = ftype == 'directory',
|
||||
started = watches.started,
|
||||
}
|
||||
poll_internal(filepath_join(path, name), opts, callback, watches.children[name])
|
||||
end
|
||||
@ -150,6 +156,8 @@ local function poll_internal(path, opts, callback, watches)
|
||||
watches.children = newchildren
|
||||
end
|
||||
|
||||
watches.started = true
|
||||
|
||||
return watches.cancel
|
||||
end
|
||||
|
||||
|
@ -1550,8 +1550,15 @@ local patterns_text = {
|
||||
['^SNNS pattern definition file'] = 'snnspat',
|
||||
['^SNNS result file'] = 'snnsres',
|
||||
['^%%.-[Vv]irata'] = { 'virata', { start_lnum = 1, end_lnum = 5 } },
|
||||
['[0-9:%.]* *execve%('] = 'strace',
|
||||
['^__libc_start_main'] = 'strace',
|
||||
function(lines)
|
||||
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
|
||||
['^\\* $$ JOB\\>'] = { 'vsejcl', { vim_regex = true } },
|
||||
['^// *JOB\\>'] = { 'vsejcl', { vim_regex = true } },
|
||||
|
@ -345,8 +345,10 @@ function M.normalize(path, opts)
|
||||
end
|
||||
|
||||
path = path:gsub('\\', '/'):gsub('/+', '/')
|
||||
|
||||
return path:sub(-1) == '/' and path:sub(1, -2) or path
|
||||
if iswin and path:match('^%w:/$') then
|
||||
return path
|
||||
end
|
||||
return (path:gsub('(.)/$', '%1'))
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -20,6 +20,22 @@ function M.report_error(msg, ...)
|
||||
vim.fn['health#report_error'](msg, ...)
|
||||
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)
|
||||
if path:match('%.lua$') then
|
||||
-- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp"
|
||||
|
@ -5,7 +5,7 @@ local loaders = package.loaders
|
||||
|
||||
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}
|
||||
|
||||
---@class ModuleFindOpts
|
||||
@ -28,12 +28,11 @@ M.enabled = false
|
||||
---@field _rtp string[]
|
||||
---@field _rtp_pure string[]
|
||||
---@field _rtp_key string
|
||||
---@field _hashes? table<string, CacheHash>
|
||||
local Loader = {
|
||||
VERSION = 3,
|
||||
---@type table<string, table<string,ModuleInfo>>
|
||||
_indexed = {},
|
||||
---@type table<string, CacheHash>
|
||||
_hashes = {},
|
||||
---@type table<string, string[]>
|
||||
_topmods = {},
|
||||
_loadfile = loadfile,
|
||||
@ -44,9 +43,13 @@ local Loader = {
|
||||
}
|
||||
|
||||
--- @param path string
|
||||
--- @return uv.fs_stat.result
|
||||
--- @return CacheHash
|
||||
--- @private
|
||||
function Loader.get_hash(path)
|
||||
if not Loader._hashes then
|
||||
return uv.fs_stat(path) --[[@as CacheHash]]
|
||||
end
|
||||
|
||||
if not Loader._hashes[path] then
|
||||
-- Note we must never save a stat for a non-existent path.
|
||||
-- For non-existent paths fs_stat() will return nil.
|
||||
@ -163,13 +166,16 @@ end
|
||||
---@return string|function
|
||||
---@private
|
||||
function Loader.loader(modname)
|
||||
Loader._hashes = {}
|
||||
local ret = M.find(modname)[1]
|
||||
if ret then
|
||||
-- Make sure to call the global loadfile so we respect any augmentations done elsewhere.
|
||||
-- E.g. profiling
|
||||
local chunk, err = loadfile(ret.modpath)
|
||||
Loader._hashes = nil
|
||||
return chunk or error(err)
|
||||
end
|
||||
Loader._hashes = nil
|
||||
return '\ncache_loader: module ' .. modname .. ' not found'
|
||||
end
|
||||
|
||||
@ -373,7 +379,9 @@ function M.reset(path)
|
||||
end
|
||||
|
||||
-- Path could be a directory so just clear all the hashes.
|
||||
Loader._hashes = {}
|
||||
if Loader._hashes then
|
||||
Loader._hashes = {}
|
||||
end
|
||||
end
|
||||
|
||||
--- Enables the experimental Lua module loader:
|
||||
|
@ -933,8 +933,7 @@ end
|
||||
--- |vim.lsp.protocol.make_client_capabilities()|, passed to the language
|
||||
--- server on initialization. Hint: use make_client_capabilities() and modify
|
||||
--- its result.
|
||||
--- - Note: To send an empty dictionary use
|
||||
--- `{[vim.type_idx]=vim.types.dictionary}`, else it will be encoded as an
|
||||
--- - Note: To send an empty dictionary use |vim.empty_dict()|, else it will be encoded as an
|
||||
--- array.
|
||||
---
|
||||
--- - handlers: Map of language server method names to |lsp-handler|
|
||||
|
@ -193,21 +193,30 @@ local to_lsp_change_type = {
|
||||
function M.register(reg, ctx)
|
||||
local client_id = ctx.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
|
||||
end
|
||||
local watch_regs = {}
|
||||
for _, w in ipairs(reg.registerOptions.watchers) do
|
||||
local relative_pattern = false
|
||||
local glob_patterns = {}
|
||||
if type(w.globPattern) == 'string' then
|
||||
for _, folder in ipairs(client.workspace_folders) do
|
||||
table.insert(glob_patterns, { baseUri = folder.uri, pattern = w.globPattern })
|
||||
end
|
||||
else
|
||||
relative_pattern = true
|
||||
table.insert(glob_patterns, w.globPattern)
|
||||
end
|
||||
for _, glob_pattern in ipairs(glob_patterns) do
|
||||
local pattern = parse(glob_pattern.pattern)
|
||||
local base_dir = nil
|
||||
if type(glob_pattern.baseUri) == 'string' then
|
||||
base_dir = glob_pattern.baseUri
|
||||
@ -216,9 +225,16 @@ function M.register(reg, ctx)
|
||||
end
|
||||
assert(base_dir, "couldn't identify root of watch")
|
||||
base_dir = vim.uri_to_fname(base_dir)
|
||||
|
||||
local kind = w.kind
|
||||
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, {
|
||||
base_dir = base_dir,
|
||||
pattern = pattern,
|
||||
|
@ -135,6 +135,10 @@ end
|
||||
---@param bufnr integer
|
||||
---@param client_id integer
|
||||
function M.display(lenses, bufnr, client_id)
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
local ns = namespaces[client_id]
|
||||
if not lenses or not next(lenses) then
|
||||
api.nvim_buf_clear_namespace(bufnr, ns, 0, -1)
|
||||
@ -180,6 +184,10 @@ end
|
||||
---@param bufnr integer
|
||||
---@param client_id integer
|
||||
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]
|
||||
if not lenses_by_client then
|
||||
lenses_by_client = {}
|
||||
@ -220,19 +228,24 @@ local function resolve_lenses(lenses, bufnr, client_id, callback)
|
||||
countdown()
|
||||
else
|
||||
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
|
||||
-- Eager display to have some sort of incremental feedback
|
||||
-- Once all lenses got resolved there will be a full redraw for all lenses
|
||||
-- So that multiple lens per line are properly displayed
|
||||
api.nvim_buf_set_extmark(
|
||||
bufnr,
|
||||
ns,
|
||||
lens.range.start.line,
|
||||
0,
|
||||
{ virt_text = { { lens.command.title, 'LspCodeLens' } }, hl_mode = 'combine' }
|
||||
)
|
||||
|
||||
local num_lines = api.nvim_buf_line_count(bufnr)
|
||||
if lens.range.start.line <= num_lines then
|
||||
api.nvim_buf_set_extmark(
|
||||
bufnr,
|
||||
ns,
|
||||
lens.range.start.line,
|
||||
0,
|
||||
{ virt_text = { { lens.command.title, 'LspCodeLens' } }, hl_mode = 'combine' }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
countdown()
|
||||
end, bufnr)
|
||||
end
|
||||
|
@ -1,7 +1,8 @@
|
||||
local api = vim.api
|
||||
local bit = require('bit')
|
||||
local handlers = require('vim.lsp.handlers')
|
||||
local util = require('vim.lsp.util')
|
||||
local bit = require('bit')
|
||||
local uv = vim.loop
|
||||
|
||||
--- @class STTokenRange
|
||||
--- @field line integer line number 0-based
|
||||
@ -94,15 +95,39 @@ end
|
||||
---
|
||||
---@private
|
||||
---@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 token_types = legend.tokenTypes
|
||||
local token_modifiers = legend.tokenModifiers
|
||||
local lines = api.nvim_buf_get_lines(bufnr, 0, -1, false)
|
||||
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 start_char = 0
|
||||
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]
|
||||
line = line and line + delta_line or delta_line
|
||||
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)
|
||||
|
||||
---@private
|
||||
local function _get_byte_pos(char_pos)
|
||||
return util._get_line_byte_from_position(bufnr, {
|
||||
line = line,
|
||||
character = char_pos,
|
||||
}, client.offset_encoding)
|
||||
local function _get_byte_pos(col)
|
||||
if col > 0 then
|
||||
local buf_line = lines[line + 1] or ''
|
||||
local ok, result
|
||||
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
|
||||
|
||||
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 highlighter = STHighlighter.active[ctx.bufnr]
|
||||
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, self.bufnr)
|
||||
|
||||
@ -315,11 +346,9 @@ function STHighlighter:process_response(response, client, version)
|
||||
return
|
||||
end
|
||||
|
||||
-- reset active request
|
||||
state.active_request = {}
|
||||
|
||||
-- skip nil responses
|
||||
if response == nil then
|
||||
state.active_request = {}
|
||||
return
|
||||
end
|
||||
|
||||
@ -347,12 +376,19 @@ function STHighlighter:process_response(response, client, version)
|
||||
tokens = response.data
|
||||
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
|
||||
current_result.version = version
|
||||
current_result.result_id = response.resultId
|
||||
current_result.tokens = tokens
|
||||
current_result.highlights = tokens_to_ranges(tokens, self.bufnr, client)
|
||||
current_result.highlights = highlights
|
||||
current_result.namespace_cleared = false
|
||||
|
||||
-- redraw all windows displaying buffer
|
||||
|
@ -253,12 +253,17 @@ local function get_lines(bufnr, rows)
|
||||
---@private
|
||||
local function buf_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]
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
-- use loaded buffers if available
|
||||
if vim.fn.bufloaded(bufnr) == 1 then
|
||||
return buf_lines()
|
||||
end
|
||||
|
||||
local uri = vim.uri_from_bufnr(bufnr)
|
||||
|
||||
-- load the buffer if this is not a file uri
|
||||
@ -268,11 +273,6 @@ local function get_lines(bufnr, rows)
|
||||
return buf_lines()
|
||||
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)
|
||||
|
||||
-- get the data from the file
|
||||
|
@ -100,10 +100,9 @@ function vim.gsplit(s, sep, opts)
|
||||
local start = 1
|
||||
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_segs = 0 -- Empty segments found between non-empty segments.
|
||||
local nonemptyseg = nil
|
||||
|
||||
local function _pass(i, j, ...)
|
||||
if i then
|
||||
@ -118,14 +117,9 @@ function vim.gsplit(s, sep, opts)
|
||||
end
|
||||
|
||||
return function()
|
||||
if trimempty and empty_segs > 0 then
|
||||
-- trimempty: Pop the collected empty segments.
|
||||
empty_segs = empty_segs - 1
|
||||
return ''
|
||||
elseif trimempty and nonemptyseg then
|
||||
local seg = nonemptyseg
|
||||
nonemptyseg = nil
|
||||
return seg
|
||||
if trimempty and #segs > 0 then
|
||||
-- trimempty: Pop the collected segments.
|
||||
return table.remove(segs)
|
||||
elseif done or (s == '' and sep == '') then
|
||||
return nil
|
||||
elseif sep == '' then
|
||||
@ -138,21 +132,24 @@ function vim.gsplit(s, sep, opts)
|
||||
local seg = _pass(s:find(sep, start, plain))
|
||||
|
||||
-- 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
|
||||
empty_segs = empty_segs + 1
|
||||
table.insert(segs, 1, '')
|
||||
seg = _pass(s:find(sep, start, plain))
|
||||
end
|
||||
if done and seg == '' then
|
||||
return nil
|
||||
elseif empty_start then
|
||||
empty_start = false
|
||||
empty_segs = 0
|
||||
segs = {}
|
||||
return seg
|
||||
end
|
||||
nonemptyseg = seg ~= '' and seg or nil
|
||||
seg = ''
|
||||
empty_segs = empty_segs - 1
|
||||
if seg ~= '' then
|
||||
table.insert(segs, 1, seg)
|
||||
end
|
||||
return table.remove(segs)
|
||||
end
|
||||
|
||||
return seg
|
||||
|
@ -136,16 +136,6 @@ function M.get_parser(bufnr, lang, opts)
|
||||
return parsers[bufnr]
|
||||
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
|
||||
---
|
||||
---@param str string Text to parse
|
||||
|
@ -32,15 +32,58 @@ function FoldInfo:invalidate_range(srow, erow)
|
||||
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
|
||||
---@param srow integer
|
||||
---@param erow integer
|
||||
function FoldInfo:remove_range(srow, erow)
|
||||
for i = erow - 1, srow, -1 do
|
||||
table.remove(self.levels, i + 1)
|
||||
table.remove(self.levels0, i + 1)
|
||||
table.remove(self.start_counts, i + 1)
|
||||
table.remove(self.stop_counts, i + 1)
|
||||
list_remove(self.levels, srow + 1, erow)
|
||||
list_remove(self.levels0, srow + 1, erow)
|
||||
list_remove(self.start_counts, srow + 1, erow)
|
||||
list_remove(self.stop_counts, srow + 1, erow)
|
||||
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
|
||||
|
||||
@ -48,12 +91,10 @@ end
|
||||
---@param srow integer
|
||||
---@param erow integer
|
||||
function FoldInfo:add_range(srow, erow)
|
||||
for i = srow, erow - 1 do
|
||||
table.insert(self.levels, i + 1, '-1')
|
||||
table.insert(self.levels0, i + 1, -1)
|
||||
table.insert(self.start_counts, i + 1, nil)
|
||||
table.insert(self.stop_counts, i + 1, nil)
|
||||
end
|
||||
list_insert(self.levels, srow + 1, erow, '-1')
|
||||
list_insert(self.levels0, srow + 1, erow, -1)
|
||||
list_insert(self.start_counts, srow + 1, erow, nil)
|
||||
list_insert(self.stop_counts, srow + 1, erow, nil)
|
||||
end
|
||||
|
||||
---@package
|
||||
@ -184,13 +225,25 @@ local function recompute_folds()
|
||||
vim._foldupdate()
|
||||
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 foldinfo TS.FoldInfo
|
||||
---@param tree_changes Range4[]
|
||||
local function on_changedtree(bufnr, foldinfo, tree_changes)
|
||||
-- For some reason, queries seem to use the old buffer state in on_bytes.
|
||||
-- Get around this by scheduling and manually updating folds.
|
||||
vim.schedule(function()
|
||||
schedule_if_loaded(bufnr, function()
|
||||
for _, change in ipairs(tree_changes) do
|
||||
local srow, _, erow = Range.unpack4(change)
|
||||
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)
|
||||
elseif new_row > old_row then
|
||||
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)
|
||||
recompute_folds()
|
||||
end)
|
||||
@ -226,7 +279,8 @@ function M.foldexpr(lnum)
|
||||
lnum = lnum or vim.v.lnum
|
||||
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'
|
||||
end
|
||||
|
||||
@ -234,7 +288,6 @@ function M.foldexpr(lnum)
|
||||
foldinfos[bufnr] = FoldInfo.new()
|
||||
get_folds_levels(bufnr, foldinfos[bufnr])
|
||||
|
||||
local parser = vim.treesitter.get_parser(bufnr)
|
||||
parser:register_cbs({
|
||||
on_changedtree = function(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> }
|
||||
self.tree = tree
|
||||
tree:register_cbs({
|
||||
on_changedtree = function(...)
|
||||
self:on_changedtree(...)
|
||||
end,
|
||||
on_bytes = function(...)
|
||||
self:on_bytes(...)
|
||||
end,
|
||||
@ -87,6 +84,17 @@ function TSHighlighter.new(tree, opts)
|
||||
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.edit_count = 0
|
||||
self.redraw_count = 0
|
||||
@ -177,10 +185,10 @@ function TSHighlighter:on_detach()
|
||||
end
|
||||
|
||||
---@package
|
||||
---@param changes integer[][]?
|
||||
---@param changes Range6[][]
|
||||
function TSHighlighter:on_changedtree(changes)
|
||||
for _, ch in ipairs(changes or {}) do
|
||||
api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[3] + 1)
|
||||
for _, ch in ipairs(changes) do
|
||||
api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[4] + 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -51,8 +51,18 @@ local Range = require('vim.treesitter._range')
|
||||
---| 'on_child_added'
|
||||
---| '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
|
||||
---@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 _injection_query Query Queries defining injected languages
|
||||
---@field private _opts table Options
|
||||
@ -79,7 +89,7 @@ LanguageTree.__index = LanguageTree
|
||||
--- "injected" language parsers, which themselves may inject other languages, recursively.
|
||||
---
|
||||
---@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:
|
||||
--- - injections table Map of language to injection query strings. Overrides the
|
||||
--- built-in runtime file searching for language injections.
|
||||
@ -89,6 +99,10 @@ function LanguageTree.new(source, lang, opts)
|
||||
---@type LanguageTreeOpts
|
||||
opts = opts or {}
|
||||
|
||||
if source == 0 then
|
||||
source = vim.api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
local injections = opts.injections or {}
|
||||
local self = setmetatable({
|
||||
_source = source,
|
||||
@ -100,15 +114,15 @@ function LanguageTree.new(source, lang, opts)
|
||||
or query.get(lang, 'injections'),
|
||||
_valid = false,
|
||||
_parser = vim._create_ts_parser(lang),
|
||||
_callbacks = {
|
||||
changedtree = {},
|
||||
bytes = {},
|
||||
detach = {},
|
||||
child_added = {},
|
||||
child_removed = {},
|
||||
},
|
||||
_callbacks = {},
|
||||
_callbacks_rec = {},
|
||||
}, LanguageTree)
|
||||
|
||||
for _, name in pairs(TSCallbackNames) do
|
||||
self._callbacks[name] = {}
|
||||
self._callbacks_rec[name] = {}
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -121,6 +135,7 @@ local function tcall(f, ...)
|
||||
local start = vim.loop.hrtime()
|
||||
---@diagnostic disable-next-line
|
||||
local r = { f(...) }
|
||||
--- @type number
|
||||
local duration = (vim.loop.hrtime() - start) / 1000000
|
||||
return duration, unpack(r)
|
||||
end
|
||||
@ -161,6 +176,9 @@ function LanguageTree:invalidate(reload)
|
||||
|
||||
-- buffer was reloaded, reparse all trees
|
||||
if reload then
|
||||
for _, t in ipairs(self._trees) do
|
||||
self:_do_callback('changedtree', t:included_ranges(true), t)
|
||||
end
|
||||
self._trees = {}
|
||||
end
|
||||
|
||||
@ -245,9 +263,12 @@ function LanguageTree:parse()
|
||||
if not self._valid or not self._valid[i] then
|
||||
self._parser:set_included_ranges(ranges)
|
||||
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
|
||||
vim.list_extend(changes, tree_changes)
|
||||
|
||||
@ -341,7 +362,14 @@ function LanguageTree:add_child(lang)
|
||||
self:remove_child(lang)
|
||||
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:_do_callback('child_added', self._children[lang])
|
||||
|
||||
@ -453,6 +481,10 @@ function LanguageTree:set_included_regions(new_regions)
|
||||
end
|
||||
|
||||
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:invalidate()
|
||||
else
|
||||
@ -489,11 +521,13 @@ end
|
||||
---@param node TSNode
|
||||
---@param source string|integer
|
||||
---@param metadata TSMetadata
|
||||
---@param include_children boolean
|
||||
---@return Range6[]
|
||||
local function get_node_ranges(node, source, metadata, include_children)
|
||||
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 }
|
||||
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)
|
||||
|
||||
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 c_srow, c_scol, c_sbyte, c_erow, c_ecol, c_ebyte = child:range(true)
|
||||
if c_srow > srow or c_scol > scol then
|
||||
@ -533,7 +568,10 @@ end
|
||||
---@param combined boolean
|
||||
---@param ranges Range6[]
|
||||
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.
|
||||
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
|
||||
cb(...)
|
||||
end
|
||||
for _, cb in ipairs(self._callbacks_rec[cb_name]) do
|
||||
cb(...)
|
||||
end
|
||||
end
|
||||
|
||||
---@package
|
||||
@ -855,30 +896,26 @@ end
|
||||
--- changed.
|
||||
--- - `on_child_added` : emitted when a child is added to 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>
|
||||
if not cbs then
|
||||
return
|
||||
end
|
||||
|
||||
if cbs.on_changedtree then
|
||||
table.insert(self._callbacks.changedtree, cbs.on_changedtree)
|
||||
local callbacks = recursive and self._callbacks_rec or self._callbacks
|
||||
|
||||
for name, cbname in pairs(TSCallbackNames) do
|
||||
if cbs[name] then
|
||||
table.insert(callbacks[cbname], cbs[name])
|
||||
end
|
||||
end
|
||||
|
||||
if cbs.on_bytes then
|
||||
table.insert(self._callbacks.bytes, cbs.on_bytes)
|
||||
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)
|
||||
if recursive then
|
||||
self:for_each_child(function(child)
|
||||
child:register_cbs(cbs, true)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -147,7 +147,7 @@ local decor_ns = api.nvim_create_namespace('ts.playground')
|
||||
---@param end_lnum integer
|
||||
---@param end_col integer
|
||||
---@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
|
||||
return string.format('[%d:%d - %d]', lnum + 1, col + 1, end_col)
|
||||
end
|
||||
|
@ -458,7 +458,7 @@ local directive_handlers = {
|
||||
metadata[id] = {}
|
||||
end
|
||||
|
||||
local pattern, replacement = pred[3], pred[3]
|
||||
local pattern, replacement = pred[3], pred[4]
|
||||
assert(type(pattern) == 'string')
|
||||
assert(type(replacement) == 'string')
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
||||
</screenshots>
|
||||
|
||||
<releases>
|
||||
<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-02-02" version="0.8.3"/>
|
||||
<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
|
||||
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,
|
||||
\ })
|
||||
" hide terminal buffer
|
||||
@ -430,7 +430,7 @@ func s:StartDebug_prompt(dict)
|
||||
" call ch_log('executing "' . join(gdb_cmd) . '"')
|
||||
let s:gdbjob = jobstart(gdb_cmd, {
|
||||
\ '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
|
||||
echoerr 'invalid argument (or job table is full) while starting gdb job'
|
||||
@ -594,6 +594,23 @@ func s:PromptInterrupt()
|
||||
endif
|
||||
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.
|
||||
func s:GdbOutCallback(job_id, msgs, event)
|
||||
"call ch_log('received from gdb: ' . a:text)
|
||||
|
@ -13,7 +13,8 @@
|
||||
(preproc_else)
|
||||
(preproc_ifdef)
|
||||
(initializer_list)
|
||||
(gnu_asm_expression)
|
||||
] @fold
|
||||
|
||||
(compound_statement
|
||||
(compound_statement
|
||||
(compound_statement) @fold)
|
||||
|
@ -1,5 +1,6 @@
|
||||
; Lower priority to prefer @parameter when identifier appears in parameter_declaration.
|
||||
((identifier) @variable (#set! "priority" 95))
|
||||
(preproc_def (preproc_arg) @variable)
|
||||
|
||||
[
|
||||
"default"
|
||||
@ -8,9 +9,14 @@
|
||||
"typedef"
|
||||
"union"
|
||||
"goto"
|
||||
"asm"
|
||||
"__asm__"
|
||||
] @keyword
|
||||
|
||||
"sizeof" @keyword.operator
|
||||
[
|
||||
"sizeof"
|
||||
"offsetof"
|
||||
] @keyword.operator
|
||||
|
||||
"return" @keyword.return
|
||||
|
||||
@ -36,6 +42,8 @@
|
||||
"#else"
|
||||
"#elif"
|
||||
"#endif"
|
||||
"#elifdef"
|
||||
"#elifndef"
|
||||
(preproc_directive)
|
||||
] @preproc
|
||||
|
||||
@ -43,7 +51,7 @@
|
||||
|
||||
"#include" @include
|
||||
|
||||
[ ";" ":" "," ] @punctuation.delimiter
|
||||
[ ";" ":" "," "::" ] @punctuation.delimiter
|
||||
|
||||
"..." @punctuation.special
|
||||
|
||||
@ -98,8 +106,8 @@
|
||||
(comma_expression [ "," ] @operator)
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
(true)
|
||||
(false)
|
||||
] @boolean
|
||||
|
||||
(conditional_expression [ "?" ":" ] @conditional.ternary)
|
||||
@ -112,23 +120,31 @@
|
||||
(number_literal) @number
|
||||
(char_literal) @character
|
||||
|
||||
[
|
||||
(preproc_arg)
|
||||
(preproc_defined)
|
||||
] @function.macro
|
||||
((preproc_arg) @function.macro (#set! "priority" 90))
|
||||
(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
|
||||
|
||||
[
|
||||
(type_identifier)
|
||||
(sized_type_specifier)
|
||||
(type_descriptor)
|
||||
] @type
|
||||
|
||||
(storage_class_specifier) @storageclass
|
||||
|
||||
(type_qualifier) @type.qualifier
|
||||
[
|
||||
(type_qualifier)
|
||||
(gnu_asm_qualifier)
|
||||
] @type.qualifier
|
||||
|
||||
(linkage_specification
|
||||
"extern" @storageclass)
|
||||
@ -138,8 +154,12 @@
|
||||
|
||||
(primitive_type) @type.builtin
|
||||
|
||||
(sized_type_specifier _ @type.builtin type: _?)
|
||||
|
||||
((identifier) @constant
|
||||
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||
(preproc_def (preproc_arg) @constant
|
||||
(#lua-match? @constant "^[A-Z][A-Z0-9_]+$"))
|
||||
(enumerator
|
||||
name: (identifier) @constant)
|
||||
(case_statement
|
||||
@ -147,6 +167,8 @@
|
||||
|
||||
((identifier) @constant.builtin
|
||||
(#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
|
||||
@ -163,6 +185,10 @@
|
||||
field: (field_identifier) @function.call))
|
||||
(function_declarator
|
||||
declarator: (identifier) @function)
|
||||
(function_declarator
|
||||
declarator: (parenthesized_declarator
|
||||
(pointer_declarator
|
||||
declarator: (field_identifier) @function)))
|
||||
(preproc_function_def
|
||||
name: (identifier) @function.macro)
|
||||
|
||||
@ -175,6 +201,9 @@
|
||||
(parameter_declaration
|
||||
declarator: (identifier) @parameter)
|
||||
|
||||
(parameter_declaration
|
||||
declarator: (array_declarator) @parameter)
|
||||
|
||||
(parameter_declaration
|
||||
declarator: (pointer_declarator) @parameter)
|
||||
|
||||
@ -182,15 +211,15 @@
|
||||
|
||||
[
|
||||
"__attribute__"
|
||||
"__declspec"
|
||||
"__based"
|
||||
"__cdecl"
|
||||
"__clrcall"
|
||||
"__stdcall"
|
||||
"__fastcall"
|
||||
"__thiscall"
|
||||
"__vectorcall"
|
||||
"_unaligned"
|
||||
"__unaligned"
|
||||
"__declspec"
|
||||
(ms_pointer_modifier)
|
||||
(attribute_declaration)
|
||||
] @attribute
|
||||
|
||||
|
@ -127,8 +127,14 @@
|
||||
|
||||
(identifier) @variable
|
||||
|
||||
((identifier) @constant.builtin
|
||||
(#eq? @constant.builtin "_VERSION"))
|
||||
|
||||
((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
|
||||
(#eq? @keyword.coroutine "coroutine"))
|
||||
@ -174,13 +180,40 @@
|
||||
|
||||
(parameters (identifier) @parameter)
|
||||
|
||||
(function_call name: (identifier) @function.call)
|
||||
(function_declaration name: (identifier) @function)
|
||||
(function_declaration
|
||||
name: [
|
||||
(identifier) @function
|
||||
(dot_index_expression
|
||||
field: (identifier) @function)
|
||||
])
|
||||
|
||||
(function_call name: (dot_index_expression field: (identifier) @function.call))
|
||||
(function_declaration name: (dot_index_expression field: (identifier) @function))
|
||||
(function_declaration
|
||||
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
|
||||
(identifier) @function.builtin
|
||||
@ -208,7 +241,9 @@
|
||||
|
||||
(number) @number
|
||||
|
||||
(string) @string @spell
|
||||
(string) @string
|
||||
|
||||
(escape_sequence) @string.escape
|
||||
|
||||
;; Error
|
||||
(ERROR) @error
|
||||
|
@ -13,6 +13,14 @@
|
||||
(#set! injection.language "vim")
|
||||
(#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
|
||||
name: (_) @_vimcmd_identifier
|
||||
arguments: (arguments (string content: _ @injection.content) .))
|
||||
@ -20,7 +28,7 @@
|
||||
(#any-of? @_vimcmd_identifier "vim.treesitter.query.set" "vim.treesitter.query.parse"))
|
||||
|
||||
;; highlight string as query if starts with `;; query`
|
||||
((string ("string_content") @injection.content)
|
||||
(string content: _ @injection.content
|
||||
(#set! injection.language "query")
|
||||
(#lua-match? @injection.content "^%s*;+%s?query"))
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
||||
((parameters (identifier) @number)
|
||||
(#match? @number "^[-+]?[0-9]+(.[0-9]+)?$"))
|
||||
|
||||
((program . (comment) @include)
|
||||
(#match? @include "^;\ +inherits\ *:"))
|
||||
((program . (comment)* . (comment) @include)
|
||||
(#lua-match? @include "^;+ *inherits *:"))
|
||||
|
||||
((program . (comment) @preproc)
|
||||
(#match? @preproc "^; +extends"))
|
||||
((program . (comment)* . (comment) @preproc)
|
||||
(#lua-match? @preproc "^;+ *extends"))
|
||||
|
@ -275,7 +275,7 @@
|
||||
|
||||
; Options
|
||||
((set_value) @number
|
||||
(#match? @number "^[0-9]+(\.[0-9]+)?$"))
|
||||
(#lua-match? @number "^[%d]+(%.[%d]+)?$"))
|
||||
|
||||
(inv_option "!" @operator)
|
||||
(set_item "?" @operator)
|
||||
|
@ -1,7 +1,7 @@
|
||||
(h1) @text.title
|
||||
(h2) @text.title
|
||||
(h3) @text.title
|
||||
(column_heading) @text.title
|
||||
(h1) @text.title.1
|
||||
(h2) @text.title.2
|
||||
(h3) @text.title.3
|
||||
(column_heading) @text.title.4
|
||||
(column_heading
|
||||
"~" @conceal (#set! conceal ""))
|
||||
(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
|
||||
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
|
||||
|
||||
lua<<
|
||||
local props = {}
|
||||
for k in pairs(require('editorconfig').properties) do
|
||||
props[#props + 1] = k
|
||||
end
|
||||
vim.cmd(string.format('syntax keyword editorconfigProperty %s', table.concat(props, ' ')))
|
||||
local props = vim.tbl_keys(require('editorconfig').properties)
|
||||
vim.cmd.syntax { 'keyword', 'editorconfigProperty', unpack(props) }
|
||||
.
|
||||
|
||||
hi def link editorconfigProperty dosiniLabel
|
||||
|
@ -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}.
|
||||
|
||||
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.
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
||||
"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.",
|
||||
"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.",
|
||||
"441": "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.",
|
||||
"504": -1,
|
||||
"523": -1,
|
||||
"546": "Usually the best time to see the flowers is in the spring.",
|
||||
|
@ -217,7 +217,6 @@ CONFIG = {
|
||||
'util.lua',
|
||||
'log.lua',
|
||||
'rpc.lua',
|
||||
'sync.lua',
|
||||
'protocol.lua',
|
||||
],
|
||||
'files': [
|
||||
|
@ -26,7 +26,7 @@ APP_DIR="$APP.AppDir"
|
||||
########################################################################
|
||||
|
||||
# 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
|
||||
|
||||
########################################################################
|
||||
|
@ -146,11 +146,7 @@ if(HAS_DIAG_COLOR_FLAG)
|
||||
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)
|
||||
endif()
|
||||
option(CI_BUILD "CI, extra flags will be set" OFF)
|
||||
if(CI_BUILD)
|
||||
message(STATUS "CI build enabled")
|
||||
if(MSVC)
|
||||
@ -280,6 +276,7 @@ set(LUA_FILETYPE_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/runtime/lua/vim/filetype.lu
|
||||
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(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(API_HEADERS api/*.h)
|
||||
@ -391,11 +388,14 @@ foreach(gen_cdef DO_NOT_DEFINE_EMPTY_ATTRIBUTES ${prop})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
get_target_property(prop main_lib INTERFACE_INCLUDE_DIRECTORIES)
|
||||
foreach(gen_include ${prop})
|
||||
list(APPEND gen_cflags "-I${gen_include}")
|
||||
get_directory_property(targets BUILDSYSTEM_TARGETS)
|
||||
foreach(target ${targets})
|
||||
get_target_property(prop ${target} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
foreach(gen_include ${prop})
|
||||
list(APPEND gen_cflags "-I${gen_include}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
list(APPEND gen_cflags "-I${DEPS_PREFIX}/include")
|
||||
|
||||
if(APPLE AND CMAKE_OSX_SYSROOT)
|
||||
list(APPEND gen_cflags "-isysroot")
|
||||
list(APPEND gen_cflags "${CMAKE_OSX_SYSROOT}")
|
||||
@ -779,6 +779,15 @@ install(DIRECTORY ${BINARY_LIB_DIR}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/nvim/
|
||||
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)
|
||||
if(MSVC)
|
||||
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
|
||||
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:
|
||||
|
||||
```
|
||||
./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
|
||||
debug the remote-ui process multiple times without losing editor state.
|
||||
|
@ -114,7 +114,7 @@ Array nvim_get_autocmds(Dict(get_autocmds) *opts, Error *err)
|
||||
break;
|
||||
case kObjectTypeInteger:
|
||||
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, {
|
||||
goto cleanup;
|
||||
});
|
||||
@ -608,7 +608,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err)
|
||||
FOR_ALL_AUEVENTS(event) {
|
||||
FOREACH_ITEM(patterns, pat_object, {
|
||||
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;
|
||||
}
|
||||
});
|
||||
@ -619,7 +619,7 @@ void nvim_clear_autocmds(Dict(clear_autocmds) *opts, Error *err)
|
||||
|
||||
FOREACH_ITEM(patterns, pat_object, {
|
||||
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;
|
||||
}
|
||||
});
|
||||
@ -684,7 +684,7 @@ void nvim_del_augroup_by_id(Integer id, Error *err)
|
||||
FUNC_API_SINCE(9)
|
||||
{
|
||||
TRY_WRAP(err, {
|
||||
char *name = augroup_name((int)id);
|
||||
char *name = id == 0 ? NULL : augroup_name((int)id);
|
||||
augroup_del(name, false);
|
||||
});
|
||||
}
|
||||
@ -746,7 +746,7 @@ void nvim_exec_autocmds(Object event, Dict(exec_autocmds) *opts, Error *err)
|
||||
break;
|
||||
case kObjectTypeInteger:
|
||||
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, {
|
||||
goto cleanup;
|
||||
});
|
||||
@ -840,7 +840,7 @@ static int get_augroup_from_object(Object group, Error *err)
|
||||
return au_group;
|
||||
case kObjectTypeInteger:
|
||||
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, {
|
||||
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, {
|
||||
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.
|
||||
// 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
|
||||
|
||||
for (int j = 0; hls[j].name && hls[j].val; j++) {
|
||||
for (int j = 0; hls[j].name; j++) {
|
||||
if (hls[j].val) {
|
||||
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) \
|
||||
do { \
|
||||
const size_t len_ = (size_t)(len); \
|
||||
const char *const str_ = (const char *)(str); \
|
||||
const char *const str_ = (str); \
|
||||
assert(len_ == 0 || str_ != NULL); \
|
||||
kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
|
||||
} 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)
|
||||
{
|
||||
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);
|
||||
ui_attach_impl(ui, channel_id);
|
||||
|
||||
may_trigger_vim_suspend_resume(false);
|
||||
}
|
||||
|
||||
/// @deprecated
|
||||
@ -232,6 +239,10 @@ void nvim_ui_set_focus(uint64_t channel_id, Boolean gained, Error *error)
|
||||
return;
|
||||
}
|
||||
|
||||
if (gained) {
|
||||
may_trigger_vim_suspend_resume(false);
|
||||
}
|
||||
|
||||
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++;
|
||||
|
||||
char **buf = &data->buf_wptr;
|
||||
mpack_array(buf, 4);
|
||||
mpack_array(buf, 5);
|
||||
mpack_uint(buf, (uint32_t)grid);
|
||||
mpack_uint(buf, (uint32_t)row);
|
||||
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);
|
||||
int last_hl = -1;
|
||||
uint32_t nelem = 0;
|
||||
bool was_space = false;
|
||||
for (size_t i = 0; i < ncells; i++) {
|
||||
repeat++;
|
||||
if (i == ncells - 1 || attrs[i] != attrs[i + 1]
|
||||
|| 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,
|
||||
// flush, and start a new "grid_line" event at the current position.
|
||||
// For simplicity leave place for the final "clear" element
|
||||
// as well, hence the factor of 2 in the check.
|
||||
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);
|
||||
|
||||
prepare_call(ui, "grid_line");
|
||||
data->ncalls++;
|
||||
mpack_array(buf, 4);
|
||||
mpack_array(buf, 5);
|
||||
mpack_uint(buf, (uint32_t)grid);
|
||||
mpack_uint(buf, (uint32_t)row);
|
||||
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);
|
||||
nelem++;
|
||||
mpack_array(buf, csize);
|
||||
mpack_str(buf, (const char *)chunk[i]);
|
||||
mpack_str(buf, chunk[i]);
|
||||
if (csize >= 2) {
|
||||
mpack_uint(buf, (uint32_t)attrs[i]);
|
||||
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);
|
||||
last_hl = attrs[i];
|
||||
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++;
|
||||
data->ncells_pending += 1;
|
||||
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_w2(&lenpos, nelem);
|
||||
mpack_bool(buf, flags & kLineFlagWrap);
|
||||
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < endcol - startcol; i++) {
|
||||
remote_ui_cursor_goto(ui, row, startcol + 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]))) {
|
||||
data->client_col = -1; // force cursor update
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void grid_clear(Integer grid)
|
||||
FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
|
||||
void grid_cursor_goto(Integer grid, Integer row, Integer col)
|
||||
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;
|
||||
void grid_scroll(Integer grid, Integer top, Integer bot, Integer left, Integer right, Integer rows,
|
||||
Integer cols)
|
||||
|
@ -305,6 +305,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_ks)
|
||||
Integer nvim_input(String keys)
|
||||
FUNC_API_SINCE(1) FUNC_API_FAST
|
||||
{
|
||||
may_trigger_vim_suspend_resume(false);
|
||||
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)
|
||||
FUNC_API_SINCE(6) FUNC_API_FAST
|
||||
{
|
||||
may_trigger_vim_suspend_resume(false);
|
||||
|
||||
if (button.data == NULL || action.data == NULL) {
|
||||
goto error;
|
||||
}
|
||||
@ -428,7 +431,7 @@ String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt, Bool
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1686,6 +1689,7 @@ static void write_msg(String message, bool to_err, bool writeln)
|
||||
if (c == NL) { \
|
||||
kv_push(line_buf, NUL); \
|
||||
msg(line_buf.items); \
|
||||
msg_didout = true; \
|
||||
kv_drop(line_buf, kv_size(line_buf)); \
|
||||
kv_resize(line_buf, LINE_BUFFER_MIN_SIZE); \
|
||||
} else { \
|
||||
@ -2173,6 +2177,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
||||
linenr_T lnum = statuscol_lnum;
|
||||
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);
|
||||
wp->w_scwidth = win_signcol_count(wp);
|
||||
|
||||
statuscol.sattrs = sattrs;
|
||||
statuscol.foldinfo = fold_info(wp, lnum);
|
||||
@ -2240,7 +2245,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
|
||||
if (highlights) {
|
||||
Array hl_values = ARRAY_DICT_INIT;
|
||||
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,
|
||||
// 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++) {
|
||||
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];
|
||||
char *hi_name = syn_id2name(hi_id);
|
||||
if (hi_name[0]) {
|
||||
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));
|
||||
} else {
|
||||
ADD(border, STRING_OBJ(s));
|
||||
@ -293,10 +293,9 @@ Dictionary nvim_win_get_config(Window window, Error *err)
|
||||
VirtText title_datas = config->title_chunks;
|
||||
for (size_t i = 0; i < title_datas.size; i++) {
|
||||
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) {
|
||||
ADD(tuple,
|
||||
STRING_OBJ(cstr_to_string((const char *)syn_id2name(title_datas.items[i].hl_id))));
|
||||
ADD(tuple, STRING_OBJ(cstr_to_string(syn_id2name(title_datas.items[i].hl_id))));
|
||||
}
|
||||
ADD(titles, ARRAY_OBJ(tuple));
|
||||
}
|
||||
|
@ -1230,8 +1230,7 @@ static void get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rett
|
||||
tv_list_alloc_ret(rettv, argcount);
|
||||
if (arglist != NULL) {
|
||||
for (int idx = 0; idx < argcount; idx++) {
|
||||
tv_list_append_string(rettv->vval.v_list,
|
||||
(const char *)alist_name(&arglist[idx]), -1);
|
||||
tv_list_append_string(rettv->vval.v_list, alist_name(&arglist[idx]), -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1267,7 +1266,7 @@ void f_argv(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
rettv->vval.v_string = NULL;
|
||||
int idx = (int)tv_get_number_chk(&argvars[0], NULL);
|
||||
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) {
|
||||
get_arglist_as_rettv(arglist, argcount, rettv);
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/state.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/ui_compositor.h"
|
||||
#include "nvim/vim.h"
|
||||
@ -1421,6 +1422,8 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
|
||||
aco->save_curwin_handle = curwin->handle;
|
||||
aco->save_curbuf = curbuf;
|
||||
aco->save_prevwin_handle = prevwin == NULL ? 0 : prevwin->handle;
|
||||
aco->save_State = State;
|
||||
|
||||
if (win != NULL) {
|
||||
// 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
|
||||
@ -1495,8 +1498,14 @@ void aucmd_restbuf(aco_save_T *aco)
|
||||
}
|
||||
}
|
||||
win_found:
|
||||
;
|
||||
const bool save_stop_insert_mode = stop_insert_mode;
|
||||
// May need to stop Insert mode if we were in a prompt buffer.
|
||||
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.
|
||||
win_remove(curwin, NULL);
|
||||
pmap_del(handle_T)(&window_handles, curwin->handle);
|
||||
@ -1743,6 +1752,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.
|
||||
char *save_autocmd_fname = autocmd_fname;
|
||||
bool save_autocmd_fname_full = autocmd_fname_full;
|
||||
int save_autocmd_bufnr = autocmd_bufnr;
|
||||
char *save_autocmd_match = autocmd_match;
|
||||
int save_autocmd_busy = autocmd_busy;
|
||||
@ -1771,6 +1781,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
// Allocate MAXPATHL for when eval_vars() resolves the fullpath.
|
||||
autocmd_fname = xstrnsave(autocmd_fname, MAXPATHL);
|
||||
}
|
||||
autocmd_fname_full = false; // call FullName_save() later
|
||||
|
||||
// Set the buffer number to be used for <abuf>.
|
||||
if (buf == NULL) {
|
||||
@ -1818,6 +1829,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
|| event == EVENT_USER || event == EVENT_WINCLOSED
|
||||
|| event == EVENT_WINRESIZED || event == EVENT_WINSCROLLED) {
|
||||
fname = xstrdup(fname);
|
||||
autocmd_fname_full = true; // don't expand it later
|
||||
} else {
|
||||
fname = FullName_save(fname, false);
|
||||
}
|
||||
@ -1951,6 +1963,7 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
estack_pop();
|
||||
xfree(autocmd_fname);
|
||||
autocmd_fname = save_autocmd_fname;
|
||||
autocmd_fname_full = save_autocmd_fname_full;
|
||||
autocmd_bufnr = save_autocmd_bufnr;
|
||||
autocmd_match = save_autocmd_match;
|
||||
current_sctx = save_current_sctx;
|
||||
@ -2499,7 +2512,7 @@ bool aupat_is_buflocal(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>"
|
||||
if (patlen == 8) {
|
||||
@ -2713,6 +2726,30 @@ static bool arg_autocmd_flag_get(bool *flag, char **cmd_ptr, char *pattern, int
|
||||
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
|
||||
void do_autocmd_uienter(uint64_t chanid, bool attached)
|
||||
{
|
||||
|
@ -32,6 +32,7 @@ typedef struct {
|
||||
bufref_T new_curbuf; ///< new curbuf
|
||||
char *globaldir; ///< saved value of globaldir
|
||||
bool save_VIsual_active; ///< saved VIsual_active
|
||||
int save_State; ///< saved State
|
||||
} aco_save_T;
|
||||
|
||||
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 perm;
|
||||
|
||||
perm = os_getperm((const char *)curbuf->b_ffname);
|
||||
perm = os_getperm(curbuf->b_ffname);
|
||||
if (perm >= 0 && (0 || S_ISFIFO(perm)
|
||||
|| S_ISSOCK(perm)
|
||||
# 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
|
||||
// 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) {
|
||||
return -1;
|
||||
}
|
||||
@ -3309,8 +3309,7 @@ void maketitle(void)
|
||||
SPACE_FOR_FNAME + 1);
|
||||
buf_p += MIN(size, SPACE_FOR_FNAME);
|
||||
} else {
|
||||
buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname),
|
||||
-1, buf_p, SPACE_FOR_FNAME + 1, true);
|
||||
buf_p += transstr_buf(path_tail(curbuf->b_fname), -1, buf_p, SPACE_FOR_FNAME + 1, true);
|
||||
}
|
||||
|
||||
switch (bufIsChanged(curbuf)
|
||||
@ -3459,7 +3458,6 @@ void resettitle(void)
|
||||
{
|
||||
ui_call_set_icon(cstr_as_string(lasticon));
|
||||
ui_call_set_title(cstr_as_string(lasttitle));
|
||||
ui_flush();
|
||||
}
|
||||
|
||||
#if defined(EXITFREE)
|
||||
@ -3557,7 +3555,7 @@ void fname_expand(buf_T *buf, char **ffname, char **sfname)
|
||||
#ifdef MSWIN
|
||||
if (!buf->b_p_bin) {
|
||||
// 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) {
|
||||
xfree(*ffname);
|
||||
*ffname = rfname;
|
||||
|
@ -1223,6 +1223,9 @@ struct window_S {
|
||||
|
||||
bool w_viewport_invalid;
|
||||
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
|
||||
// that the cursor is on. We use this to avoid extra calls to plines_win().
|
||||
@ -1287,8 +1290,9 @@ struct window_S {
|
||||
linenr_T w_stl_line_count; // line count when last redrawn
|
||||
int w_stl_topfill; // topfill when last redrawn
|
||||
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_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-^)
|
||||
|
||||
|
@ -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) {
|
||||
// Do not change wl_lnum at index zero, it is used to
|
||||
// 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
|
||||
wp->w_lines[i].wl_valid = false;
|
||||
} 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
|
||||
(void)copy_option_part(&p, (char *)lead_middle, COM_MAX_LEN, ",");
|
||||
(void)copy_option_part(&p, lead_middle, COM_MAX_LEN, ",");
|
||||
require_blank = false;
|
||||
}
|
||||
|
||||
@ -1322,7 +1327,7 @@ int open_line(int dir, int flags, int second_line_indent, bool *did_do_comment)
|
||||
}
|
||||
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
|
||||
// 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++;
|
||||
}
|
||||
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
|
||||
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.
|
||||
if (lead_len > 0) {
|
||||
if (current_flag == COM_START) {
|
||||
lead_repl = (char *)lead_middle;
|
||||
lead_repl = 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.
|
||||
return true;
|
||||
}
|
||||
*error = (const char *)e_invchan;
|
||||
*error = e_invchan;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -91,19 +91,19 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
||||
if (chan->is_rpc) {
|
||||
rpc_close(chan);
|
||||
} else if (part == kChannelPartRpc) {
|
||||
*error = (const char *)e_invstream;
|
||||
*error = e_invstream;
|
||||
return false;
|
||||
}
|
||||
} else if ((part == kChannelPartStdin || part == kChannelPartStdout)
|
||||
&& chan->is_rpc) {
|
||||
*error = (const char *)e_invstreamrpc;
|
||||
*error = e_invstreamrpc;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (chan->streamtype) {
|
||||
case kChannelStreamSocket:
|
||||
if (!close_main) {
|
||||
*error = (const char *)e_invstream;
|
||||
*error = e_invstream;
|
||||
return false;
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (part == kChannelPartStderr) {
|
||||
*error = (const char *)e_invstream;
|
||||
*error = e_invstream;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case kChannelStreamStderr:
|
||||
if (part != kChannelPartAll && part != kChannelPartStderr) {
|
||||
*error = (const char *)e_invstream;
|
||||
*error = e_invstream;
|
||||
return false;
|
||||
}
|
||||
if (!chan->stream.err.closed) {
|
||||
@ -156,7 +156,7 @@ bool channel_close(uint64_t id, ChannelPart part, const char **error)
|
||||
|
||||
case kChannelStreamInternal:
|
||||
if (!close_main) {
|
||||
*error = (const char *)e_invstream;
|
||||
*error = e_invstream;
|
||||
return false;
|
||||
}
|
||||
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,
|
||||
/// 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_stderr Callback to read the job's stderr
|
||||
/// @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
|
||||
///
|
||||
/// @returns [allocated] channel
|
||||
Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader on_stderr,
|
||||
Callback on_exit, bool pty, bool rpc, bool overlapped, bool detach,
|
||||
ChannelStdinMode stdin_mode, const char *cwd, uint16_t pty_width,
|
||||
uint16_t pty_height, dict_T *env, varnumber_T *status_out)
|
||||
Channel *channel_job_start(char **argv, const char *exepath, CallbackReader on_stdout,
|
||||
CallbackReader on_stderr, Callback on_exit, bool pty, bool rpc,
|
||||
bool overlapped, bool detach, ChannelStdinMode stdin_mode,
|
||||
const char *cwd, uint16_t pty_width, uint16_t pty_height, dict_T *env,
|
||||
varnumber_T *status_out)
|
||||
{
|
||||
Channel *chan = channel_alloc(kChannelStreamProc);
|
||||
chan->on_data = on_stdout;
|
||||
@ -364,6 +366,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
|
||||
|
||||
Process *proc = &chan->stream.proc;
|
||||
proc->argv = argv;
|
||||
proc->exepath = exepath;
|
||||
proc->cb = channel_process_exit_cb;
|
||||
proc->events = chan->events;
|
||||
proc->detach = detach;
|
||||
@ -371,7 +374,7 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, CallbackReader
|
||||
proc->env = env;
|
||||
proc->overlapped = overlapped;
|
||||
|
||||
char *cmd = xstrdup(proc->argv[0]);
|
||||
char *cmd = xstrdup(process_get_exepath(proc));
|
||||
bool has_out, has_err;
|
||||
if (proc->type == kProcessTypePty) {
|
||||
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) {
|
||||
*buf_p++ = *p++;
|
||||
} 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);
|
||||
if (buf_p + tb_len > buf_e) {
|
||||
break; // Exceeded `buf` size.
|
||||
@ -645,8 +645,8 @@ size_t transchar_hex(char *const buf, const int c)
|
||||
size_t i = 0;
|
||||
|
||||
buf[i++] = '<';
|
||||
if (c > 255) {
|
||||
if (c > 255 * 256) {
|
||||
if (c > 0xFF) {
|
||||
if (c > 0xFFFF) {
|
||||
buf[i++] = (char)nr2hex((unsigned)c >> 20);
|
||||
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);
|
||||
}
|
||||
|
||||
/// 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).
|
||||
/// To be used for commands like "gf".
|
||||
///
|
||||
/// @param c character to check
|
||||
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));
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// Assume characters above 0x100 are valid (multi-byte).
|
||||
/// Explicitly interpret ']' as a wildcard character as path_has_wildcard("]")
|
||||
@ -1360,7 +1370,7 @@ char *skiptowhite(const char *p)
|
||||
/// @param p
|
||||
///
|
||||
/// @return Pointer to the next whitespace character.
|
||||
char *skiptowhite_esc(char *p)
|
||||
char *skiptowhite_esc(const char *p)
|
||||
FUNC_ATTR_PURE
|
||||
{
|
||||
while (*p != ' ' && *p != '\t' && *p != NUL) {
|
||||
@ -1369,7 +1379,7 @@ char *skiptowhite_esc(char *p)
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
return (char *)p;
|
||||
}
|
||||
|
||||
/// Skip over text until '\n' or NUL.
|
||||
|
@ -841,7 +841,7 @@ static char *find_longest_match(expand_T *xp, int options)
|
||||
char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
|
||||
{
|
||||
char *ss = NULL;
|
||||
static int findex;
|
||||
static int findex; // TODO(vim): Move into expand_T
|
||||
static char *orig_save = NULL; // kept value of orig
|
||||
int orig_saved = false;
|
||||
|
||||
@ -871,7 +871,10 @@ char *ExpandOne(expand_T *xp, char *str, char *orig, int options, int mode)
|
||||
cmdline_pum_remove();
|
||||
}
|
||||
}
|
||||
findex = 0;
|
||||
// TODO(vim): Remove condition if "findex" is part of expand_T ?
|
||||
if (mode != WILD_EXPAND_FREE && mode != WILD_ALL && mode != WILD_ALL_KEEP) {
|
||||
findex = 0;
|
||||
}
|
||||
|
||||
if (mode == WILD_FREE) { // only release file name
|
||||
return NULL;
|
||||
@ -959,7 +962,7 @@ static void showmatches_oneline(expand_T *xp, char **matches, int numMatches, in
|
||||
msg_outtrans_attr(matches[j], HL_ATTR(HLF_D));
|
||||
p = matches[j] + strlen(matches[j]) + 1;
|
||||
msg_advance(maxlen + 1);
|
||||
msg_puts((const char *)p);
|
||||
msg_puts(p);
|
||||
msg_advance(maxlen + 3);
|
||||
msg_outtrans_long_attr(p + 2, HL_ATTR(HLF_D));
|
||||
break;
|
||||
@ -1438,7 +1441,7 @@ static const char *set_cmd_index(const char *cmd, exarg_T *eap, expand_T *xp, in
|
||||
p = cmd + 1;
|
||||
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
|
||||
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) {
|
||||
eap->cmdidx = CMD_SIZE; // Ambiguous user command.
|
||||
}
|
||||
@ -1464,7 +1467,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
|
||||
// being expanded.
|
||||
xp->xp_pattern = skipwhite(arg);
|
||||
const char *p = (const char *)xp->xp_pattern;
|
||||
const char *p = xp->xp_pattern;
|
||||
while (*p != NUL) {
|
||||
int c = utf_ptr2char(p);
|
||||
if (c == '\\' && p[1] != NUL) {
|
||||
@ -1517,7 +1520,7 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use
|
||||
|
||||
// Check for environment variable.
|
||||
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))) {
|
||||
break;
|
||||
}
|
||||
@ -1533,12 +1536,11 @@ static void set_context_for_wildcard_arg(exarg_T *eap, const char *arg, bool use
|
||||
}
|
||||
// Check for user names.
|
||||
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.
|
||||
// A full match ~user<Tab> will be replaced by user's home
|
||||
// directory i.e. something like ~user<Tab> -> /home/user/
|
||||
if (*p == NUL && p > (const char *)xp->xp_pattern + 1
|
||||
&& match_user(xp->xp_pattern + 1) >= 1) {
|
||||
if (*p == NUL && p > xp->xp_pattern + 1 && match_user(xp->xp_pattern + 1) >= 1) {
|
||||
xp->xp_context = EXPAND_USER;
|
||||
xp->xp_pattern++;
|
||||
}
|
||||
@ -1550,13 +1552,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)
|
||||
{
|
||||
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) {
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
return NULL;
|
||||
}
|
||||
return (const char *)skipwhite(arg);
|
||||
return skipwhite(arg);
|
||||
}
|
||||
|
||||
/// Set the completion context for the :match command. Returns a pointer to the
|
||||
@ -1566,13 +1568,13 @@ static const char *set_context_in_match_cmd(expand_T *xp, const char *arg)
|
||||
if (*arg == NUL || !ends_excmd(*arg)) {
|
||||
// also complete "None"
|
||||
set_context_in_echohl_cmd(xp, arg);
|
||||
arg = (const char *)skipwhite(skiptowhite(arg));
|
||||
arg = skipwhite(skiptowhite(arg));
|
||||
if (*arg != NUL) {
|
||||
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.
|
||||
@ -1605,7 +1607,7 @@ static const char *find_cmd_after_substitute_cmd(const char *arg)
|
||||
if (delim) {
|
||||
// Skip "from" part.
|
||||
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) {
|
||||
// Skip "to" part.
|
||||
@ -1637,7 +1639,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)
|
||||
{
|
||||
// Skip count.
|
||||
arg = (const char *)skipwhite(skipdigits(arg));
|
||||
arg = skipwhite(skipdigits(arg));
|
||||
if (*arg != '/') {
|
||||
return NULL;
|
||||
}
|
||||
@ -1649,7 +1651,7 @@ static const char *find_cmd_after_isearch_cmd(expand_T *xp, const char *arg)
|
||||
}
|
||||
}
|
||||
if (*arg) {
|
||||
arg = (const char *)skipwhite(arg + 1);
|
||||
arg = skipwhite(arg + 1);
|
||||
|
||||
// Check for trailing illegal characters.
|
||||
if (*arg == NUL || strchr("|\"\n", *arg) == NULL) {
|
||||
@ -1666,7 +1668,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)
|
||||
{
|
||||
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;
|
||||
@ -1683,7 +1685,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.
|
||||
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) {
|
||||
xp->xp_context = EXPAND_LANGUAGE;
|
||||
xp->xp_pattern = (char *)arg;
|
||||
@ -1876,11 +1878,11 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
||||
case CMD_dsplit:
|
||||
return find_cmd_after_isearch_cmd(xp, arg);
|
||||
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_doautoall:
|
||||
return (const char *)set_context_in_autocmd(xp, (char *)arg, true);
|
||||
return set_context_in_autocmd(xp, (char *)arg, true);
|
||||
case CMD_set:
|
||||
set_context_in_set_cmd(xp, (char *)arg, 0);
|
||||
break;
|
||||
@ -1957,7 +1959,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
||||
case CMD_bwipeout:
|
||||
case CMD_bunload:
|
||||
while ((xp->xp_pattern = strchr(arg, ' ')) != NULL) {
|
||||
arg = (const char *)xp->xp_pattern + 1;
|
||||
arg = xp->xp_pattern + 1;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
case CMD_buffer:
|
||||
@ -2063,7 +2065,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
||||
case CMD_tunmenu:
|
||||
case CMD_popup:
|
||||
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:
|
||||
xp->xp_context = EXPAND_COLORS;
|
||||
@ -2126,7 +2128,7 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, expa
|
||||
|
||||
case CMD_argdelete:
|
||||
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_pattern = (char *)arg;
|
||||
@ -2186,7 +2188,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] ..
|
||||
cmd = (const char *)skip_range(cmd, &xp->xp_context);
|
||||
cmd = skip_range(cmd, &xp->xp_context);
|
||||
xp->xp_pattern = (char *)cmd;
|
||||
if (*cmd == NUL) {
|
||||
return NULL;
|
||||
@ -2218,7 +2220,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
||||
ea.argt = excmd_get_argt(ea.cmdidx);
|
||||
}
|
||||
|
||||
const char *arg = (const char *)skipwhite(p);
|
||||
const char *arg = skipwhite(p);
|
||||
|
||||
// Skip over ++argopt argument
|
||||
if ((ea.argt & EX_ARGOPT) && *arg != NUL && strncmp(arg, "++", 2) == 0) {
|
||||
@ -2226,7 +2228,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
||||
while (*p && !ascii_isspace(*p)) {
|
||||
MB_PTR_ADV(p);
|
||||
}
|
||||
arg = (const char *)skipwhite(p);
|
||||
arg = skipwhite(p);
|
||||
}
|
||||
|
||||
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
|
||||
@ -2234,7 +2236,7 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
||||
if (*++arg == '>') {
|
||||
arg++;
|
||||
}
|
||||
arg = (const char *)skipwhite(arg);
|
||||
arg = skipwhite(arg);
|
||||
} else if (*arg == '!' && ea.cmdidx == CMD_write) { // :w !filter
|
||||
arg++;
|
||||
usefilter = true;
|
||||
@ -2253,14 +2255,14 @@ static const char *set_one_cmd_context(expand_T *xp, const char *buff)
|
||||
while (*arg == *cmd) { // allow any number of '>' or '<'
|
||||
arg++;
|
||||
}
|
||||
arg = (const char *)skipwhite(arg);
|
||||
arg = skipwhite(arg);
|
||||
}
|
||||
|
||||
// Does command allow "+command"?
|
||||
if ((ea.argt & EX_CMDARG) && !usefilter && *arg == '+') {
|
||||
// Check if we're in the +command
|
||||
p = arg + 1;
|
||||
arg = (const char *)skip_cmd_arg((char *)arg, false);
|
||||
arg = skip_cmd_arg((char *)arg, false);
|
||||
|
||||
// Still touching the command after '+'?
|
||||
if (*arg == NUL) {
|
||||
@ -2268,7 +2270,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.
|
||||
arg = (const char *)skipwhite(arg);
|
||||
arg = skipwhite(arg);
|
||||
}
|
||||
|
||||
// Check for '|' to separate commands and '"' to start comments.
|
||||
@ -2344,7 +2346,7 @@ void set_cmd_context(expand_T *xp, char *str, int len, int col, int use_ccline)
|
||||
old_char = str[col];
|
||||
}
|
||||
str[col] = NUL;
|
||||
const char *nextcomm = (const char *)str;
|
||||
const char *nextcomm = str;
|
||||
|
||||
if (use_ccline && ccline->cmdfirstc == '=') {
|
||||
// pass CMD_SIZE because there is no real command
|
||||
@ -2922,7 +2924,7 @@ static void expand_shellcmd_onedir(char *buf, char *s, size_t l, char *pat, char
|
||||
// Check if this name was already found.
|
||||
hash_T hash = hash_hash(name + l);
|
||||
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)) {
|
||||
// Remove the path that was prepended.
|
||||
STRMOVE(name, name + l);
|
||||
@ -3166,7 +3168,7 @@ static int ExpandUserList(expand_T *xp, char ***matches, int *numMatches)
|
||||
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);
|
||||
|
||||
@ -3195,7 +3197,7 @@ static int ExpandUserLua(expand_T *xp, int *num_file, char ***file)
|
||||
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);
|
||||
|
||||
@ -3479,7 +3481,6 @@ void wildmenu_cleanup(CmdlineInfo *cclp)
|
||||
/// "getcompletion()" function
|
||||
void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
char *pat;
|
||||
expand_T xpc;
|
||||
bool filtered = false;
|
||||
int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
|
||||
@ -3511,9 +3512,10 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
const char *pattern = tv_get_string(&argvars[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_col = (int)strlen(pattern);
|
||||
xpc.xp_col = cmdline_len;
|
||||
goto theend;
|
||||
}
|
||||
|
||||
@ -3540,6 +3542,8 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
}
|
||||
|
||||
theend:
|
||||
;
|
||||
char *pat;
|
||||
if (cmdline_fuzzy_completion_supported(&xpc)) {
|
||||
// when fuzzy matching, don't modify the search string
|
||||
pat = xstrdup(xpc.xp_pattern);
|
||||
@ -3551,8 +3555,7 @@ theend:
|
||||
tv_list_alloc_ret(rettv, xpc.xp_numfiles);
|
||||
|
||||
for (int i = 0; i < xpc.xp_numfiles; i++) {
|
||||
tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i],
|
||||
-1);
|
||||
tv_list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
|
||||
}
|
||||
xfree(pat);
|
||||
ExpandCleanup(&xpc);
|
||||
|
@ -204,7 +204,7 @@ static inline void clear_hist_entry(histentry_T *hisptr)
|
||||
/// If 'move_to_front' is true, matching entry is moved to end of history.
|
||||
///
|
||||
/// @param move_to_front Move the entry to the front if it exists
|
||||
static int in_history(int type, char *str, int move_to_front, int sep)
|
||||
static int in_history(int type, const char *str, int move_to_front, int sep)
|
||||
{
|
||||
int last_i = -1;
|
||||
|
||||
@ -238,7 +238,7 @@ static int in_history(int type, char *str, int move_to_front, int sep)
|
||||
}
|
||||
|
||||
list_T *const list = history[type][i].additional_elements;
|
||||
str = history[type][i].hisstr;
|
||||
char *const save_hisstr = history[type][i].hisstr;
|
||||
while (i != hisidx[type]) {
|
||||
if (++i >= hislen) {
|
||||
i = 0;
|
||||
@ -248,7 +248,7 @@ static int in_history(int type, char *str, int move_to_front, int sep)
|
||||
}
|
||||
tv_list_unref(list);
|
||||
history[type][i].hisnum = ++hisnum[type];
|
||||
history[type][i].hisstr = str;
|
||||
history[type][i].hisstr = save_hisstr;
|
||||
history[type][i].timestamp = os_time();
|
||||
history[type][i].additional_elements = NULL;
|
||||
return true;
|
||||
@ -295,7 +295,7 @@ static int last_maptick = -1; // last seen maptick
|
||||
/// @param histype may be one of the HIST_ values.
|
||||
/// @param in_map consider maptick when inside a mapping
|
||||
/// @param sep separator character used (search hist)
|
||||
void add_to_history(int histype, char *new_entry, int in_map, int sep)
|
||||
void add_to_history(int histype, const char *new_entry, int in_map, int sep)
|
||||
{
|
||||
histentry_T *hisptr;
|
||||
|
||||
@ -538,7 +538,7 @@ void f_histadd(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
}
|
||||
|
||||
init_history();
|
||||
add_to_history(histype, (char *)str, false, NUL);
|
||||
add_to_history(histype, str, false, NUL);
|
||||
rettv->vval.v_number = true;
|
||||
}
|
||||
|
||||
@ -622,7 +622,7 @@ void ex_history(exarg_T *eap)
|
||||
}
|
||||
histype1 = get_histtype(arg, (size_t)(end - arg), false);
|
||||
if (histype1 == HIST_INVALID) {
|
||||
if (STRNICMP(arg, "all", end - (char *)arg) == 0) {
|
||||
if (STRNICMP(arg, "all", end - arg) == 0) {
|
||||
histype1 = 0;
|
||||
histype2 = HIST_COUNT - 1;
|
||||
} else {
|
||||
|
@ -417,7 +417,9 @@ void decor_redraw_signs(buf_T *buf, int row, int *num_signs, SignTextAttrs sattr
|
||||
if (sattrs[j - 1].priority >= decor->priority) {
|
||||
break;
|
||||
}
|
||||
sattrs[j] = sattrs[j - 1];
|
||||
if (j < SIGN_SHOW_MAX) {
|
||||
sattrs[j] = sattrs[j - 1];
|
||||
}
|
||||
}
|
||||
if (j < SIGN_SHOW_MAX) {
|
||||
sattrs[j] = (SignTextAttrs) {
|
||||
@ -574,26 +576,34 @@ int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines, TriState has_fo
|
||||
return 0;
|
||||
}
|
||||
|
||||
int virt_lines = 0;
|
||||
int row = MAX(lnum - 2, 0);
|
||||
int end_row = (int)lnum;
|
||||
MarkTreeIter itr[1] = { 0 };
|
||||
marktree_itr_get(buf->b_marktree, row, 0, itr);
|
||||
assert(lnum > 0);
|
||||
bool below_fold = lnum > 1 && hasFoldingWin(wp, lnum - 1, NULL, NULL, true, NULL);
|
||||
if (has_fold == kNone) {
|
||||
has_fold = hasFoldingWin(wp, lnum, NULL, NULL, true, NULL);
|
||||
}
|
||||
|
||||
const int row = lnum - 1;
|
||||
const int start_row = below_fold ? row : MAX(row - 1, 0);
|
||||
const int end_row = has_fold ? row : row + 1;
|
||||
if (start_row >= end_row) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int virt_lines = 0;
|
||||
MarkTreeIter itr[1] = { 0 };
|
||||
marktree_itr_get(buf->b_marktree, start_row, 0, itr);
|
||||
while (true) {
|
||||
mtkey_t mark = marktree_itr_current(itr);
|
||||
if (mark.pos.row < 0 || mark.pos.row >= end_row) {
|
||||
break;
|
||||
} else if (marktree_decor_level(mark) < kDecorLevelVirtLine) {
|
||||
} else if (mt_end(mark)
|
||||
|| marktree_decor_level(mark) < kDecorLevelVirtLine
|
||||
|| !mark.decor_full) {
|
||||
goto next_mark;
|
||||
}
|
||||
bool above = mark.pos.row > (lnum - 2);
|
||||
bool has_fold_cur = above ? has_fold : below_fold;
|
||||
Decoration *decor = mark.decor_full;
|
||||
if (!has_fold_cur && decor && decor->virt_lines_above == above) {
|
||||
Decoration *const decor = mark.decor_full;
|
||||
const int draw_row = mark.pos.row + (decor->virt_lines_above ? 0 : 1);
|
||||
if (draw_row == row) {
|
||||
virt_lines += (int)kv_size(decor->virt_lines);
|
||||
if (lines) {
|
||||
kv_splice(*lines, decor->virt_lines);
|
||||
|
@ -2383,7 +2383,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin)
|
||||
towin->w_topline = lnum + (dp->df_lnum[toidx] - dp->df_lnum[fromidx]);
|
||||
|
||||
if (lnum >= dp->df_lnum[fromidx]) {
|
||||
if (diff_flags & DIFF_LINEMATCH) {
|
||||
if (dp->is_linematched) {
|
||||
calculate_topfill_and_topline(fromidx, toidx, fromwin->w_topline,
|
||||
fromwin->w_topfill, &towin->w_topfill, &towin->w_topline);
|
||||
} else {
|
||||
|
@ -2,7 +2,7 @@
|
||||
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
|
||||
// drawline.c: Functions for drawing window lines on the screen.
|
||||
// This is the middle level, drawscreen.c is the top and grid.c/screen.c the lower level.
|
||||
// This is the middle level, drawscreen.c is the top and grid.c the lower level.
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
@ -168,7 +168,7 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
|
||||
return;
|
||||
}
|
||||
|
||||
width1 = wp->w_width - cur_col_off;
|
||||
width1 = wp->w_width_inner - cur_col_off;
|
||||
width2 = width1 + win_col_off2(wp);
|
||||
|
||||
*left_col = 0;
|
||||
@ -282,7 +282,7 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
|
||||
if (item->win_col < 0) {
|
||||
continue;
|
||||
}
|
||||
int col;
|
||||
int col = 0;
|
||||
if (item->decor.ui_watched) {
|
||||
// send mark position to UI
|
||||
col = item->win_col;
|
||||
@ -342,12 +342,20 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
|
||||
schar_T dummy[2];
|
||||
int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col],
|
||||
max_col - col, false, vcol);
|
||||
// if we failed to emit a char, we still need to advance
|
||||
cells = MAX(cells, 1);
|
||||
|
||||
// If we failed to emit a char, we still need to put a space and advance.
|
||||
if (cells < 1) {
|
||||
schar_from_ascii(linebuf_char[col], ' ');
|
||||
cells = 1;
|
||||
}
|
||||
for (int c = 0; c < cells; c++) {
|
||||
linebuf_attr[col++] = attr;
|
||||
}
|
||||
if (col < max_col && linebuf_char[col][0] == 0) {
|
||||
// If the left half of a double-width char is overwritten,
|
||||
// change the right half to a space so that grid redraws properly,
|
||||
// but don't advance the current column.
|
||||
schar_from_ascii(linebuf_char[col], ' ');
|
||||
}
|
||||
vcol += cells;
|
||||
}
|
||||
return col;
|
||||
@ -656,14 +664,22 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T
|
||||
wp->w_statuscol_line_count = wp->w_nrwidth_line_count;
|
||||
set_vim_var_nr(VV_VIRTNUM, 0);
|
||||
build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, stcp);
|
||||
stcp->width += stcp->truncate;
|
||||
if (stcp->truncate > 0) {
|
||||
// Add truncated width to avoid unnecessary redraws
|
||||
int addwidth = MIN(stcp->truncate, MAX_NUMBERWIDTH - wp->w_nrwidth);
|
||||
stcp->truncate = 0;
|
||||
stcp->width += addwidth;
|
||||
wp->w_nrwidth += addwidth;
|
||||
wp->w_nrwidth_width = wp->w_nrwidth;
|
||||
wp->w_valid &= ~VALID_WCOL;
|
||||
}
|
||||
}
|
||||
set_vim_var_nr(VV_VIRTNUM, virtnum);
|
||||
|
||||
int width = build_statuscol_str(wp, lnum, relnum, stcp);
|
||||
// Force a redraw in case of error or when truncated
|
||||
if (*wp->w_p_stc == NUL || (stcp->truncate > 0 && wp->w_nrwidth < MAX_NUMBERWIDTH)) {
|
||||
if (stcp->truncate) { // Avoid truncating 'statuscolumn'
|
||||
if (stcp->truncate > 0) { // Avoid truncating 'statuscolumn'
|
||||
wp->w_nrwidth = MIN(MAX_NUMBERWIDTH, wp->w_nrwidth + stcp->truncate);
|
||||
wp->w_nrwidth_width = wp->w_nrwidth;
|
||||
} else { // 'statuscolumn' reset due to error
|
||||
@ -713,6 +729,11 @@ static void get_statuscol_display_info(statuscol_T *stcp, winlinevars_T *wlv)
|
||||
}
|
||||
// Skip over empty highlight sections
|
||||
} while (wlv->n_extra == 0 && stcp->textp < stcp->text_end);
|
||||
if (wlv->n_extra > 0) {
|
||||
static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * 2) * MB_MAXBYTES + 1];
|
||||
wlv->n_extra = (int)transstr_buf(wlv->p_extra, wlv->n_extra, transbuf, sizeof transbuf, true);
|
||||
wlv->p_extra = transbuf;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_breakindent(win_T *wp, winlinevars_T *wlv)
|
||||
@ -1378,7 +1399,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
if (v > 0 && !number_only) {
|
||||
char *prev_ptr = ptr;
|
||||
chartabsize_T cts;
|
||||
int charsize;
|
||||
int charsize = 0;
|
||||
|
||||
init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, ptr);
|
||||
while (cts.cts_vcol < v && *cts.cts_ptr != NUL) {
|
||||
@ -1582,6 +1603,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
// Draw the 'statuscolumn' if option is set.
|
||||
if (statuscol.draw) {
|
||||
if (statuscol.textp == NULL) {
|
||||
v = (ptr - line);
|
||||
get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol);
|
||||
if (!end_fill) {
|
||||
// Get the line again as evaluating 'statuscolumn' may free it.
|
||||
@ -2033,9 +2055,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
v = (ptr - line);
|
||||
if (has_spell && v >= word_end && v > cur_checked_col) {
|
||||
spell_attr = 0;
|
||||
if (!attr_pri) {
|
||||
wlv.char_attr = hl_combine_attr(wlv.char_attr, syntax_attr);
|
||||
}
|
||||
if (c != 0 && ((!has_syntax && !no_plain_buffer) || can_spell)) {
|
||||
char *prev_ptr;
|
||||
char *p;
|
||||
@ -2668,7 +2687,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) {
|
||||
col_attr = cuc_attr;
|
||||
} else if (draw_color_col && VCOL_HLC == *color_cols) {
|
||||
col_attr = mc_attr;
|
||||
col_attr = hl_combine_attr(wlv.line_attr_lowprio, mc_attr);
|
||||
}
|
||||
|
||||
col_attr = hl_combine_attr(col_attr, wlv.line_attr);
|
||||
@ -2766,9 +2785,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
wlv.char_attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.char_attr);
|
||||
}
|
||||
|
||||
if (wlv.draw_state == WL_LINE) {
|
||||
vcol_prev = wlv.vcol;
|
||||
}
|
||||
|
||||
// Store character to be displayed.
|
||||
// Skip characters that are left of the screen for 'nowrap'.
|
||||
vcol_prev = wlv.vcol;
|
||||
if (wlv.draw_state < WL_LINE || n_skip <= 0) {
|
||||
//
|
||||
// Store the character.
|
||||
@ -2796,6 +2818,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
wlv.col++;
|
||||
// UTF-8: Put a 0 in the second screen char.
|
||||
linebuf_char[wlv.off][0] = 0;
|
||||
linebuf_attr[wlv.off] = linebuf_attr[wlv.off - 1];
|
||||
if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) {
|
||||
wlv.vcol++;
|
||||
}
|
||||
@ -2967,16 +2990,17 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
wlv.need_showbreak = true;
|
||||
}
|
||||
if (statuscol.draw) {
|
||||
if (wlv.row == startrow + wlv.filler_lines + 1
|
||||
|| wlv.row == startrow + wlv.filler_lines) {
|
||||
// Re-evaluate 'statuscolumn' for the first wrapped row and non filler line
|
||||
statuscol.textp = NULL;
|
||||
} else if (statuscol.textp) {
|
||||
if (wlv.row == startrow + wlv.filler_lines) {
|
||||
statuscol.textp = NULL; // re-evaluate for first non-filler line
|
||||
} else if (vim_strchr(p_cpo, CPO_NUMCOL) && wlv.row > startrow + wlv.filler_lines) {
|
||||
statuscol.draw = false; // don't draw status column if "n" is in 'cpo'
|
||||
} else if (wlv.row == startrow + wlv.filler_lines + 1) {
|
||||
statuscol.textp = NULL; // re-evaluate for first wrapped line
|
||||
} else {
|
||||
// Draw the already built 'statuscolumn' on the next wrapped or filler line
|
||||
statuscol.textp = statuscol.text;
|
||||
statuscol.hlrecp = statuscol.hlrec;
|
||||
} // Fall back to default columns if the 'n' flag isn't in 'cpo'
|
||||
statuscol.draw = vim_strchr(p_cpo, CPO_NUMCOL) == NULL;
|
||||
}
|
||||
}
|
||||
wlv.filler_todo--;
|
||||
virt_line_offset = -1;
|
||||
|
@ -574,9 +574,9 @@ int update_screen(void)
|
||||
draw_tabline();
|
||||
}
|
||||
|
||||
// Correct stored syntax highlighting info for changes in each displayed
|
||||
// buffer. Each buffer must only be done once.
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
// Correct stored syntax highlighting info for changes in each displayed
|
||||
// buffer. Each buffer must only be done once.
|
||||
update_window_hl(wp, type >= UPD_NOT_VALID || hl_changed);
|
||||
|
||||
buf_T *buf = wp->w_buffer;
|
||||
@ -592,6 +592,13 @@ int update_screen(void)
|
||||
buf->b_mod_tick_decor = display_tick;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset 'statuscolumn' if there is no dedicated signcolumn but it is invalid.
|
||||
if (*wp->w_p_stc != NUL && !wp->w_buffer->b_signcols.valid && win_no_signcol(wp)) {
|
||||
wp->w_nrwidth_line_count = 0;
|
||||
wp->w_valid &= ~VALID_WCOL;
|
||||
wp->w_redr_type = UPD_NOT_VALID;
|
||||
}
|
||||
}
|
||||
|
||||
// Go from top to bottom through the windows, redrawing the ones that need it.
|
||||
@ -599,6 +606,11 @@ int update_screen(void)
|
||||
screen_search_hl.rm.regprog = NULL;
|
||||
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
// Validate b_signcols if there is no dedicated signcolumn but 'statuscolumn' is set.
|
||||
if (*wp->w_p_stc != NUL && win_no_signcol(wp)) {
|
||||
buf_signcols(wp->w_buffer, 0);
|
||||
}
|
||||
|
||||
if (wp->w_redr_type == UPD_CLEAR && wp->w_floating && wp->w_grid_alloc.chars) {
|
||||
grid_invalidate(&wp->w_grid_alloc);
|
||||
wp->w_redr_type = UPD_NOT_VALID;
|
||||
@ -828,7 +840,8 @@ void show_cursor_info_later(bool force)
|
||||
|| curwin->w_topfill != curwin->w_stl_topfill
|
||||
|| empty_line != curwin->w_stl_empty
|
||||
|| reg_recording != curwin->w_stl_recording
|
||||
|| state != curwin->w_stl_state) {
|
||||
|| state != curwin->w_stl_state
|
||||
|| (VIsual_active && VIsual_mode != curwin->w_stl_visual_mode)) {
|
||||
if (curwin->w_status_height || global_stl_height()) {
|
||||
curwin->w_redr_status = true;
|
||||
} else {
|
||||
@ -851,8 +864,11 @@ void show_cursor_info_later(bool force)
|
||||
curwin->w_stl_topline = curwin->w_topline;
|
||||
curwin->w_stl_line_count = curwin->w_buffer->b_ml.ml_line_count;
|
||||
curwin->w_stl_topfill = curwin->w_topfill;
|
||||
curwin->w_stl_state = state;
|
||||
curwin->w_stl_recording = reg_recording;
|
||||
curwin->w_stl_state = state;
|
||||
if (VIsual_active) {
|
||||
curwin->w_stl_visual_mode = VIsual_mode;
|
||||
}
|
||||
}
|
||||
|
||||
/// @return true when postponing displaying the mode message: when not redrawing
|
||||
@ -1052,11 +1068,11 @@ int showmode(void)
|
||||
clear_showcmd();
|
||||
}
|
||||
|
||||
// If the last window has no status line and global statusline is disabled,
|
||||
// If the current or last window has no status line and global statusline is disabled,
|
||||
// the ruler is after the mode message and must be redrawn
|
||||
win_T *last = curwin->w_floating ? curwin : lastwin_nofloating();
|
||||
if (redrawing() && last->w_status_height == 0 && global_stl_height() == 0) {
|
||||
win_redr_ruler(last);
|
||||
win_T *ruler_win = curwin->w_status_height == 0 ? curwin : lastwin_nofloating();
|
||||
if (redrawing() && ruler_win->w_status_height == 0 && global_stl_height() == 0) {
|
||||
win_redr_ruler(ruler_win);
|
||||
}
|
||||
|
||||
redraw_cmdline = false;
|
||||
@ -1397,10 +1413,6 @@ static void win_update(win_T *wp, DecorProviders *providers)
|
||||
if (type >= UPD_NOT_VALID) {
|
||||
wp->w_redr_status = true;
|
||||
wp->w_lines_valid = 0;
|
||||
if (*wp->w_p_stc != NUL) {
|
||||
wp->w_nrwidth_line_count = 0; // make sure width is reset
|
||||
wp->w_statuscol_line_count = 0; // make sure width is re-estimated
|
||||
}
|
||||
}
|
||||
|
||||
// Window is zero-height: Only need to draw the separator
|
||||
@ -2528,6 +2540,7 @@ int number_width(win_T *wp)
|
||||
|
||||
// reset for 'statuscolumn'
|
||||
if (*wp->w_p_stc != NUL) {
|
||||
wp->w_statuscol_line_count = 0; // make sure width is re-estimated
|
||||
wp->w_nrwidth_width = (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw;
|
||||
return wp->w_nrwidth_width;
|
||||
}
|
||||
|
@ -609,7 +609,9 @@ static int insert_execute(VimState *state, int key)
|
||||
}
|
||||
}
|
||||
|
||||
s->c = do_digraph(s->c);
|
||||
if (s->c != K_EVENT) {
|
||||
s->c = do_digraph(s->c);
|
||||
}
|
||||
|
||||
if ((s->c == Ctrl_V || s->c == Ctrl_Q) && ctrl_x_mode_cmdline()) {
|
||||
insert_do_complete(s);
|
||||
@ -881,7 +883,7 @@ static int insert_handle_key(InsertState *s)
|
||||
goto check_pum;
|
||||
|
||||
case K_LUA:
|
||||
map_execute_lua();
|
||||
map_execute_lua(false);
|
||||
|
||||
check_pum:
|
||||
// nvim_select_popupmenu_item() can be called from the handling of
|
||||
@ -2699,7 +2701,7 @@ int stuff_inserted(int c, long count, int no_esc)
|
||||
}
|
||||
|
||||
do {
|
||||
stuffReadbuff((const char *)ptr);
|
||||
stuffReadbuff(ptr);
|
||||
// A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
|
||||
if (last) {
|
||||
stuffReadbuff(last == '0' ? "\026\060\064\070" : "\026^");
|
||||
|
@ -396,11 +396,11 @@ void eval_init(void)
|
||||
|
||||
// add to v: scope dict, unless the value is not always available
|
||||
if (p->vv_type != VAR_UNKNOWN) {
|
||||
hash_add(&vimvarht, (char *)p->vv_di.di_key);
|
||||
hash_add(&vimvarht, p->vv_di.di_key);
|
||||
}
|
||||
if (p->vv_flags & VV_COMPAT) {
|
||||
// add to compat scope dict
|
||||
hash_add(&compat_hashtab, (char *)p->vv_di.di_key);
|
||||
hash_add(&compat_hashtab, p->vv_di.di_key);
|
||||
}
|
||||
}
|
||||
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
|
||||
@ -984,7 +984,7 @@ void prepare_vimvar(int idx, typval_T *save_tv)
|
||||
{
|
||||
*save_tv = vimvars[idx].vv_tv;
|
||||
if (vimvars[idx].vv_type == VAR_UNKNOWN) {
|
||||
hash_add(&vimvarht, (char *)vimvars[idx].vv_di.di_key);
|
||||
hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,7 +997,7 @@ void restore_vimvar(int idx, typval_T *save_tv)
|
||||
return;
|
||||
}
|
||||
|
||||
hashitem_T *hi = hash_find(&vimvarht, (char *)vimvars[idx].vv_di.di_key);
|
||||
hashitem_T *hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
|
||||
if (HASHITEM_EMPTY(hi)) {
|
||||
internal_error("restore_vimvar()");
|
||||
} else {
|
||||
@ -1145,7 +1145,7 @@ void *call_func_retlist(const char *func, int argc, typval_T *argv)
|
||||
typval_T rettv;
|
||||
|
||||
// All arguments are passed as strings, no conversion to number.
|
||||
if (call_vim_function((char *)func, argc, argv, &rettv) == FAIL) {
|
||||
if (call_vim_function(func, argc, argv, &rettv) == FAIL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1234,9 +1234,8 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
|
||||
|
||||
if (skip) {
|
||||
// When skipping just find the end of the name.
|
||||
lp->ll_name = (const char *)name;
|
||||
return (char *)find_name_end(name, NULL, NULL,
|
||||
FNE_INCL_BR | fne_flags);
|
||||
lp->ll_name = name;
|
||||
return (char *)find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
|
||||
}
|
||||
|
||||
// Find the end of the name.
|
||||
@ -1269,8 +1268,8 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
|
||||
lp->ll_name_len = strlen(lp->ll_name);
|
||||
}
|
||||
} else {
|
||||
lp->ll_name = (const char *)name;
|
||||
lp->ll_name_len = (size_t)((const char *)p - lp->ll_name);
|
||||
lp->ll_name = name;
|
||||
lp->ll_name_len = (size_t)(p - lp->ll_name);
|
||||
}
|
||||
|
||||
// Without [idx] or .key we are done.
|
||||
@ -1417,7 +1416,7 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
|
||||
}
|
||||
lp->ll_list = NULL;
|
||||
lp->ll_dict = lp->ll_tv->vval.v_dict;
|
||||
lp->ll_di = tv_dict_find(lp->ll_dict, (const char *)key, len);
|
||||
lp->ll_di = tv_dict_find(lp->ll_dict, key, len);
|
||||
|
||||
// When assigning to a scope dictionary check that a function and
|
||||
// variable name is valid (only variable name unless it is l: or
|
||||
@ -1434,8 +1433,8 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
|
||||
}
|
||||
wrong = ((lp->ll_dict->dv_scope == VAR_DEF_SCOPE
|
||||
&& tv_is_func(*rettv)
|
||||
&& var_wrong_func_name((const char *)key, lp->ll_di == NULL))
|
||||
|| !valid_varname((const char *)key));
|
||||
&& var_wrong_func_name(key, lp->ll_di == NULL))
|
||||
|| !valid_varname(key));
|
||||
if (len != -1) {
|
||||
key[len] = prevval;
|
||||
}
|
||||
@ -1728,7 +1727,7 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, int copy, const bool
|
||||
}
|
||||
|
||||
// Need to add an item to the Dictionary.
|
||||
di = tv_dict_item_alloc((const char *)lp->ll_newkey);
|
||||
di = tv_dict_item_alloc(lp->ll_newkey);
|
||||
if (tv_dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) {
|
||||
xfree(di);
|
||||
return;
|
||||
@ -1764,7 +1763,7 @@ notify:
|
||||
} else {
|
||||
dictitem_T *di_ = lp->ll_di;
|
||||
assert(di_->di_key != NULL);
|
||||
tv_dict_watcher_notify(dict, (char *)di_->di_key, lp->ll_tv, &oldtv);
|
||||
tv_dict_watcher_notify(dict, di_->di_key, lp->ll_tv, &oldtv);
|
||||
tv_clear(&oldtv);
|
||||
}
|
||||
}
|
||||
@ -1786,7 +1785,7 @@ void *eval_for_line(const char *arg, bool *errp, char **nextcmdp, int skip)
|
||||
|
||||
*errp = true; // Default: there is an error.
|
||||
|
||||
expr = skip_var_list((char *)arg, &fi->fi_varcount, &fi->fi_semicolon);
|
||||
expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
|
||||
if (expr == NULL) {
|
||||
return fi;
|
||||
}
|
||||
@ -2172,13 +2171,13 @@ static int eval_func(char **const arg, char *const name, const int name_len, typ
|
||||
int len = name_len;
|
||||
|
||||
if (!evaluate) {
|
||||
check_vars((const char *)s, (size_t)len);
|
||||
check_vars(s, (size_t)len);
|
||||
}
|
||||
|
||||
// If "s" is the name of a variable of type VAR_FUNC
|
||||
// use its contents.
|
||||
partial_T *partial;
|
||||
s = deref_func_name((const char *)s, &len, &partial, !evaluate);
|
||||
s = deref_func_name(s, &len, &partial, !evaluate);
|
||||
|
||||
// Need to make a copy, in case evaluating the arguments makes
|
||||
// the name invalid.
|
||||
@ -3000,9 +2999,9 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string)
|
||||
if (**arg == '(') { // recursive!
|
||||
ret = eval_func(arg, s, len, rettv, evaluate, NULL);
|
||||
} else if (evaluate) {
|
||||
ret = get_var_tv((const char *)s, len, rettv, NULL, true, false);
|
||||
ret = get_var_tv(s, len, rettv, NULL, true, false);
|
||||
} else {
|
||||
check_vars((const char *)s, (size_t)len);
|
||||
check_vars(s, (size_t)len);
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
@ -3036,7 +3035,7 @@ static int eval7_leader(typval_T *const rettv, const bool numeric_only,
|
||||
const char *const start_leader, const char **const end_leaderp)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
const char *end_leader = (char *)(*end_leaderp);
|
||||
const char *end_leader = *end_leaderp;
|
||||
int ret = OK;
|
||||
bool error = false;
|
||||
varnumber_T val = 0;
|
||||
@ -3199,7 +3198,7 @@ static int eval_method(char **const arg, typval_T *const rettv, const bool evalu
|
||||
char *lua_funcname = NULL;
|
||||
if (strncmp(name, "v:lua.", 6) == 0) {
|
||||
lua_funcname = name + 6;
|
||||
*arg = (char *)skip_luafunc_name((const char *)lua_funcname);
|
||||
*arg = (char *)skip_luafunc_name(lua_funcname);
|
||||
*arg = skipwhite(*arg); // to detect trailing whitespace later
|
||||
len = (int)(*arg - lua_funcname);
|
||||
} else {
|
||||
@ -3264,7 +3263,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose)
|
||||
bool empty2 = false;
|
||||
ptrdiff_t len = -1;
|
||||
int range = false;
|
||||
char *key = NULL;
|
||||
const char *key = NULL;
|
||||
|
||||
switch (rettv->v_type) {
|
||||
case VAR_FUNC:
|
||||
@ -3513,15 +3512,14 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose)
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
key = (char *)tv_get_string_chk(&var1);
|
||||
key = tv_get_string_chk(&var1);
|
||||
if (key == NULL) {
|
||||
tv_clear(&var1);
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
|
||||
(const char *)key, len);
|
||||
dictitem_T *const item = tv_dict_find(rettv->vval.v_dict, key, len);
|
||||
|
||||
if (item == NULL && verbose) {
|
||||
semsg(_(e_dictkey), key);
|
||||
@ -4635,14 +4633,14 @@ static int eval_dict(char **arg, typval_T *rettv, int evaluate, bool literal)
|
||||
goto failret;
|
||||
}
|
||||
if (evaluate) {
|
||||
dictitem_T *item = tv_dict_find(d, (const char *)key, -1);
|
||||
dictitem_T *item = tv_dict_find(d, key, -1);
|
||||
if (item != NULL) {
|
||||
semsg(_("E721: Duplicate key in Dictionary: \"%s\""), key);
|
||||
tv_clear(&tvkey);
|
||||
tv_clear(&tv);
|
||||
goto failret;
|
||||
}
|
||||
item = tv_dict_item_alloc((const char *)key);
|
||||
item = tv_dict_item_alloc(key);
|
||||
item->di_tv = tv;
|
||||
item->di_tv.v_lock = VAR_UNLOCKED;
|
||||
if (tv_dict_add(d, item) == FAIL) {
|
||||
@ -4755,8 +4753,7 @@ void assert_error(garray_T *gap)
|
||||
// Make sure v:errors is a list.
|
||||
set_vim_var_list(VV_ERRORS, tv_list_alloc(1));
|
||||
}
|
||||
tv_list_append_string(vimvars[VV_ERRORS].vv_list,
|
||||
(const char *)gap->ga_data, (ptrdiff_t)gap->ga_len);
|
||||
tv_list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, (ptrdiff_t)gap->ga_len);
|
||||
}
|
||||
|
||||
/// Implementation of map() and filter().
|
||||
@ -4831,7 +4828,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
|
||||
break;
|
||||
}
|
||||
|
||||
vimvars[VV_KEY].vv_str = xstrdup((char *)di->di_key);
|
||||
vimvars[VV_KEY].vv_str = xstrdup(di->di_key);
|
||||
int r = filter_map_one(&di->di_tv, expr, map, &rem);
|
||||
tv_clear(&vimvars[VV_KEY].vv_tv);
|
||||
if (r == FAIL || did_emsg) {
|
||||
@ -4983,14 +4980,12 @@ void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref)
|
||||
}
|
||||
if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s))
|
||||
|| (is_funcref && trans_name == NULL)) {
|
||||
semsg(_(e_invarg2), (use_string
|
||||
? tv_get_string(&argvars[0])
|
||||
: (const char *)s));
|
||||
semsg(_(e_invarg2), (use_string ? tv_get_string(&argvars[0]) : s));
|
||||
// Don't check an autoload name for existence here.
|
||||
} else if (trans_name != NULL
|
||||
&& (is_funcref
|
||||
? find_func(trans_name) == NULL
|
||||
: !translated_function_exists((const char *)trans_name))) {
|
||||
: !translated_function_exists(trans_name))) {
|
||||
semsg(_("E700: Unknown function: %s"), s);
|
||||
} else {
|
||||
int dict_idx = 0;
|
||||
@ -6190,6 +6185,10 @@ pos_T *var2fpos(const typval_T *const tv, const bool dollar_lnum, int *const ret
|
||||
pos.coladd = 0;
|
||||
|
||||
if (name[0] == 'w' && dollar_lnum) {
|
||||
// the "w_valid" flags are not reset when moving the cursor, but they
|
||||
// do matter for update_topline() and validate_botline().
|
||||
check_cursor_moved(curwin);
|
||||
|
||||
pos.col = 0;
|
||||
if (name[1] == '0') { // "w0": first visible line
|
||||
update_topline(curwin);
|
||||
@ -6338,7 +6337,7 @@ int get_id_len(const char **const arg)
|
||||
}
|
||||
|
||||
len = (int)(p - *arg);
|
||||
*arg = (const char *)skipwhite(p);
|
||||
*arg = skipwhite(p);
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -6376,7 +6375,7 @@ int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbo
|
||||
if (expr_start != NULL) {
|
||||
if (!evaluate) {
|
||||
len += (int)(p - *arg);
|
||||
*arg = (const char *)skipwhite(p);
|
||||
*arg = skipwhite(p);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -6387,7 +6386,7 @@ int get_name_len(const char **const arg, char **alias, bool evaluate, bool verbo
|
||||
return -1;
|
||||
}
|
||||
*alias = temp_string;
|
||||
*arg = (const char *)skipwhite(p);
|
||||
*arg = skipwhite(p);
|
||||
return (int)strlen(temp_string);
|
||||
}
|
||||
|
||||
@ -7612,7 +7611,7 @@ const void *var_shada_iter(const void *const iter, const char **const name, typv
|
||||
} else {
|
||||
hi = (const hashitem_T *)iter;
|
||||
}
|
||||
*name = (char *)TV_DICT_HI2DI(hi)->di_key;
|
||||
*name = TV_DICT_HI2DI(hi)->di_key;
|
||||
tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv);
|
||||
while ((size_t)(++hi - hifirst) < hinum) {
|
||||
if (!HASHITEM_EMPTY(hi) && (var_flavour(hi->hi_key) & flavour)) {
|
||||
@ -7636,10 +7635,10 @@ int store_session_globals(FILE *fd)
|
||||
TV_DICT_ITER(&globvardict, this_var, {
|
||||
if ((this_var->di_tv.v_type == VAR_NUMBER
|
||||
|| this_var->di_tv.v_type == VAR_STRING)
|
||||
&& var_flavour((char *)this_var->di_key) == VAR_FLAVOUR_SESSION) {
|
||||
&& var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
|
||||
// Escape special characters with a backslash. Turn a LF and
|
||||
// CR into \n and \r.
|
||||
char *const p = (char *)vim_strsave_escaped(tv_get_string(&this_var->di_tv), "\\\"\n\r");
|
||||
char *const p = vim_strsave_escaped(tv_get_string(&this_var->di_tv), "\\\"\n\r");
|
||||
for (char *t = p; *t != NUL; t++) {
|
||||
if (*t == '\n') {
|
||||
*t = 'n';
|
||||
@ -7658,7 +7657,7 @@ int store_session_globals(FILE *fd)
|
||||
}
|
||||
xfree(p);
|
||||
} else if (this_var->di_tv.v_type == VAR_FLOAT
|
||||
&& var_flavour((char *)this_var->di_key) == VAR_FLAVOUR_SESSION) {
|
||||
&& var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
|
||||
float_T f = this_var->di_tv.vval.v_float;
|
||||
int sign = ' ';
|
||||
|
||||
@ -7949,7 +7948,7 @@ repeat:
|
||||
// "path/to/this.file.ext" :r:r:r
|
||||
// ^ ^------------- tail
|
||||
// +--------------------- *fnamep
|
||||
if (s > MAX(tail, (char *)(*fnamep))) {
|
||||
if (s > MAX(tail, *fnamep)) {
|
||||
*fnamelen = (size_t)(s - *fnamep);
|
||||
}
|
||||
}
|
||||
@ -8165,7 +8164,7 @@ void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
|
||||
list_T *args = tv_list_alloc(1);
|
||||
tv_list_append_string(args, (const char *)argvars[0].vval.v_string, -1);
|
||||
tv_list_append_string(args, argvars[0].vval.v_string, -1);
|
||||
*rettv = eval_call_provider(name, "eval", args, false);
|
||||
}
|
||||
|
||||
@ -8193,6 +8192,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments, boo
|
||||
.es_entry = ((estack_T *)exestack.ga_data)[exestack.ga_len - 1],
|
||||
.autocmd_fname = autocmd_fname,
|
||||
.autocmd_match = autocmd_match,
|
||||
.autocmd_fname_full = autocmd_fname_full,
|
||||
.autocmd_bufnr = autocmd_bufnr,
|
||||
.funccalp = (void *)get_current_funccal()
|
||||
};
|
||||
|
@ -487,8 +487,7 @@ static dict_T *get_buffer_info(buf_T *buf)
|
||||
dict_T *const dict = tv_dict_alloc();
|
||||
|
||||
tv_dict_add_nr(dict, S_LEN("bufnr"), buf->b_fnum);
|
||||
tv_dict_add_str(dict, S_LEN("name"),
|
||||
buf->b_ffname != NULL ? (const char *)buf->b_ffname : "");
|
||||
tv_dict_add_str(dict, S_LEN("name"), buf->b_ffname != NULL ? buf->b_ffname : "");
|
||||
tv_dict_add_nr(dict, S_LEN("lnum"),
|
||||
buf == curbuf ? curwin->w_cursor.lnum : buflist_findlnum(buf));
|
||||
tv_dict_add_nr(dict, S_LEN("linecount"), buf->b_ml.ml_line_count);
|
||||
@ -496,8 +495,7 @@ static dict_T *get_buffer_info(buf_T *buf)
|
||||
tv_dict_add_nr(dict, S_LEN("listed"), buf->b_p_bl);
|
||||
tv_dict_add_nr(dict, S_LEN("changed"), bufIsChanged(buf));
|
||||
tv_dict_add_nr(dict, S_LEN("changedtick"), buf_get_changedtick(buf));
|
||||
tv_dict_add_nr(dict, S_LEN("hidden"),
|
||||
buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0);
|
||||
tv_dict_add_nr(dict, S_LEN("hidden"), buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0);
|
||||
|
||||
// Get a reference to buffer variables
|
||||
tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars);
|
||||
@ -609,8 +607,7 @@ static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retli
|
||||
}
|
||||
tv_list_alloc_ret(rettv, end - start + 1);
|
||||
while (start <= end) {
|
||||
tv_list_append_string(rettv->vval.v_list,
|
||||
(const char *)ml_get_buf(buf, start++, false), -1);
|
||||
tv_list_append_string(rettv->vval.v_list, ml_get_buf(buf, start++, false), -1);
|
||||
}
|
||||
} else {
|
||||
rettv->v_type = VAR_STRING;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user