mirror of
https://github.com/neovim/neovim
synced 2025-07-21 22:02:16 +00:00
Compare commits
362 Commits
Author | SHA1 | Date | |
---|---|---|---|
e96f75a4e6 | |||
8d420a32db | |||
fdcdf560da | |||
22a327a20e | |||
d63848c918 | |||
a6c54fdfc1 | |||
a7392c04d9 | |||
7908900859 | |||
a8eddf1eb1 | |||
938a600847 | |||
3a50639331 | |||
f132efaefb | |||
46cc8a52b2 | |||
a3cc513b67 | |||
a986048cb0 | |||
d7ee06124d | |||
ca10442e01 | |||
4b25fe09cc | |||
baaaf6a9e7 | |||
e477ac7c45 | |||
3b5c2213fd | |||
5aabe5695f | |||
b0b383bff9 | |||
323c43e1c4 | |||
2bc5e1be0f | |||
87440e7bc5 | |||
357ee88606 | |||
6a6c6b2658 | |||
79030bf196 | |||
aa2b69b178 | |||
b36cadcb8e | |||
d8149e5af9 | |||
4e1b1b6fd7 | |||
9b5ee7df4e | |||
1a030f6e04 | |||
bf66871113 | |||
424a452401 | |||
01fe4fc589 | |||
7abc58349e | |||
8fbe3e3941 | |||
71faa2be88 | |||
650dcbbafe | |||
6a63034b51 | |||
b5b84b806a | |||
950048b206 | |||
7ca0408a1f | |||
78a36cdd55 | |||
694c3992ea | |||
9695650c0c | |||
7781111fef | |||
4007c42b77 | |||
584b811aee | |||
a930b2666e | |||
c36c4ddae2 | |||
308e9719cf | |||
e80e8a0980 | |||
163a532cfa | |||
1a12dea191 | |||
6f2786433d | |||
085f1cc99d | |||
3c0e1a89d9 | |||
57b0fecd47 | |||
f8ee92feec | |||
98ec48eefb | |||
34a976ec2b | |||
6a07b199ff | |||
6550227110 | |||
b7f025e45b | |||
6c12cfe18c | |||
7774ca9107 | |||
348a939168 | |||
9455686b6f | |||
1a4e78832f | |||
fb5a0e28db | |||
b286ba419a | |||
94f44122ad | |||
0b0385ea6a | |||
84bbbd9fbe | |||
bbefbc995e | |||
97aaea3478 | |||
1a02f1835f | |||
2d1a13bdf5 | |||
27fca9c7d2 | |||
5480c0bd75 | |||
c257fe5582 | |||
ee7885aa21 | |||
82ea8a7c3f | |||
8b98642002 | |||
687c0078c2 | |||
68a2259804 | |||
aa83d866c1 | |||
f31e29fce4 | |||
045afa9e8a | |||
1fc09b0738 | |||
28fba3bf27 | |||
2f3c447605 | |||
9b4e7c9a0d | |||
6a0d1eee46 | |||
c9d7ad4a34 | |||
d535482ab2 | |||
e537379641 | |||
3a23149cfc | |||
b380a8fe21 | |||
6a44055a71 | |||
2a8d80a442 | |||
53e37391e8 | |||
b65e978a23 | |||
1db8824fbc | |||
d5a0e4ec5b | |||
983482626d | |||
8d842a301c | |||
e63e0a2e06 | |||
50a021e653 | |||
2c95d48083 | |||
ba47b440fd | |||
9d7711a732 | |||
a3f9bd7f79 | |||
017a054e82 | |||
d63d379eec | |||
fa4bd6994d | |||
4abd480e8f | |||
b4824edac1 | |||
e464b8c90d | |||
260ac4b3a2 | |||
d585f3103d | |||
f3675337f0 | |||
b020b66005 | |||
6f34f07a31 | |||
23a9c67f1b | |||
61b0816790 | |||
1e1e4066b1 | |||
ef05c514aa | |||
e13564b9f4 | |||
b55435f438 | |||
461ed5e6bd | |||
8611f4dcf0 | |||
95c3fd4dc0 | |||
59d3d76b79 | |||
886a8b62c5 | |||
26b72b0f91 | |||
1fe8dc4d2c | |||
5cb3505ab8 | |||
0f6f5c4682 | |||
b5a2d52a36 | |||
797f524337 | |||
8aea03f7b2 | |||
974447bfc3 | |||
6ed530baa5 | |||
d000c56373 | |||
2a32ec784c | |||
c7e943a181 | |||
d874ba319d | |||
b18538527e | |||
a6b2233c3e | |||
d593b20017 | |||
7834d80b81 | |||
1ed493cc96 | |||
dca6c4e92c | |||
40671f18f7 | |||
316fa168a1 | |||
be831a725d | |||
1fd86be15c | |||
7284400a34 | |||
3ca127063b | |||
ca6f8ee267 | |||
e4492677ee | |||
1f58e27600 | |||
b0bac2a339 | |||
9f8a5cd022 | |||
4552a9629a | |||
eec37b6e6b | |||
339067ab7e | |||
ee57bb5a8e | |||
dd0f6afa00 | |||
2e1f656eb7 | |||
05e72488b9 | |||
187c93d7e5 | |||
6aba2f3944 | |||
21157459fe | |||
5955ef0ba8 | |||
3af1495af0 | |||
1fda01fa55 | |||
771b3a52c5 | |||
7550947157 | |||
c43dd3ef6f | |||
a0a95edb2d | |||
c2625b6fad | |||
ad393c1fc1 | |||
4ad864dd09 | |||
bce2364f60 | |||
006fd0304c | |||
7e15526dd2 | |||
85ac560947 | |||
7e194f0d0c | |||
70f7708cdf | |||
0d293e4315 | |||
ffc457a1dc | |||
575136c178 | |||
f77db12995 | |||
18a9ae169e | |||
804a94d300 | |||
0389472961 | |||
9fd6664ba7 | |||
5cdf0c22bd | |||
4150e5e6fd | |||
8c88f402e1 | |||
3d319092d5 | |||
6527f5e2d2 | |||
ad55ec350c | |||
125b253e7b | |||
b01202df15 | |||
d6437e2ca5 | |||
97be9d8563 | |||
2fb69ccaf7 | |||
0e81c62405 | |||
68513c2a89 | |||
eb53aba5af | |||
e13f03af85 | |||
24fa65a500 | |||
b94b341ef2 | |||
410f43c0ae | |||
677eb23c38 | |||
a03cc83bfb | |||
a333847f6b | |||
6136326d63 | |||
7400f9dfe5 | |||
2ae8bb7b96 | |||
19787d6057 | |||
f654a30093 | |||
29fd7432fd | |||
b2587a0665 | |||
891cc78179 | |||
94aacc2695 | |||
ceb82a9396 | |||
bddbbd874c | |||
576363a0fb | |||
c467bfeb93 | |||
4ce293c2c3 | |||
fde5718e62 | |||
a430944ea7 | |||
7c055bd74b | |||
113e5a91de | |||
07de890de6 | |||
ae9aa58f9c | |||
7582d4a7b5 | |||
8c00651131 | |||
ba90b54301 | |||
46d2906332 | |||
978b63a9f1 | |||
cb9ccedf04 | |||
33121f1eae | |||
24ee2e7c74 | |||
8fe17036ba | |||
63ff7338ea | |||
f39fb4c11e | |||
b397b5672c | |||
bc1e168e49 | |||
c35e040b7e | |||
ab2d243fd0 | |||
5cad641848 | |||
f89d4ee6ce | |||
d6a73d7314 | |||
2d7aab623e | |||
28a5923aea | |||
65776124b1 | |||
2845d05569 | |||
356ddb1305 | |||
803cc08c17 | |||
91e337a477 | |||
f76d0dc91e | |||
35f6425207 | |||
9c6efd0a65 | |||
259a620eb8 | |||
3b8d0721af | |||
eadc4e03a2 | |||
17fe405adc | |||
f82d7b8200 | |||
b16fe558ae | |||
34cc49bd72 | |||
ad82e11eb7 | |||
db65017e60 | |||
2eafe248c4 | |||
3725db69ef | |||
9f2aec2629 | |||
f7d8650616 | |||
446b05f85a | |||
891b235df0 | |||
1ab52dff9a | |||
0827279ff5 | |||
77b0970cda | |||
643d6af451 | |||
4d9114d3ab | |||
a784b901be | |||
0608444447 | |||
981548b7f7 | |||
728f6c7c83 | |||
18a36d3d9f | |||
8a8c3ed4dc | |||
aa1321801d | |||
0ee3147bc7 | |||
46c2962b3a | |||
b6b2272573 | |||
dfff482efe | |||
8dece36427 | |||
7055cd1238 | |||
f1fba12803 | |||
1fe1f8556e | |||
94d8f6bde8 | |||
f03348472d | |||
571e54e12c | |||
704d33634e | |||
4c53b9c0a1 | |||
df6ce8377f | |||
58e1ef2f65 | |||
c3aef56199 | |||
d8ff216040 | |||
89fa1ee822 | |||
88cd7a6cdd | |||
fdf769fa86 | |||
b36458b363 | |||
b98aa783f3 | |||
039121f5a3 | |||
e98637e8c0 | |||
b9e540cc70 | |||
b322c3560b | |||
8d1467ce9a | |||
5d9f2d7ecc | |||
565fccbeeb | |||
3a354bfcaa | |||
bec397edda | |||
4efca7cda5 | |||
84d7bfcf16 | |||
777e15fa61 | |||
ebc6c38cde | |||
bf16fe3f01 | |||
28f03205be | |||
7e878da7dd | |||
21b21b94e6 | |||
e1b6187801 | |||
bdd5871dc5 | |||
10a16c1311 | |||
3a727beafd | |||
efe8a0a520 | |||
4f0c4c3921 | |||
4e9864147a | |||
89f29fcc92 | |||
671073e714 | |||
dffadc392e | |||
1e62f8e15c | |||
8e239ed9ea | |||
6a1c0e9574 | |||
d6756fc0a5 | |||
c6ebb931d9 | |||
9c91233a38 | |||
81560bbdbf | |||
9a2760a01f | |||
5eaae797af | |||
ea6b2b78bd | |||
0cf7e2570c | |||
902980edb9 | |||
6802db7aa1 | |||
d90ee70897 |
6
.github/scripts/install_deps.sh
vendored
6
.github/scripts/install_deps.sh
vendored
@ -16,7 +16,7 @@ if [[ $os == Linux ]]; then
|
||||
|
||||
if [[ $CC == clang ]]; then
|
||||
DEFAULT_CLANG_VERSION=$(echo | clang -dM -E - | grep __clang_major | awk '{print $3}')
|
||||
CLANG_VERSION=18
|
||||
CLANG_VERSION=19
|
||||
if ((DEFAULT_CLANG_VERSION >= CLANG_VERSION)); then
|
||||
echo "Default clang version is $DEFAULT_CLANG_VERSION, which equal or larger than wanted version $CLANG_VERSION. Aborting!"
|
||||
exit 1
|
||||
@ -30,10 +30,10 @@ if [[ $os == Linux ]]; then
|
||||
fi
|
||||
|
||||
if [[ -n $TEST ]]; then
|
||||
sudo apt-get install -y locales-all cpanminus attr libattr1-dev gdb fswatch
|
||||
sudo apt-get install -y locales-all cpanminus attr libattr1-dev gdb fswatch xdg-utils
|
||||
|
||||
# Use default CC to avoid compilation problems when installing Python modules
|
||||
CC=cc python3 -m pip -q install --user --upgrade pynvim
|
||||
CC=cc python3 -m pip -q install --user --upgrade --break-system-packages pynvim
|
||||
fi
|
||||
elif [[ $os == Darwin ]]; then
|
||||
brew update --quiet
|
||||
|
20
.github/scripts/labeler_configuration.yml
vendored
20
.github/scripts/labeler_configuration.yml
vendored
@ -2,6 +2,10 @@ build:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ CMakeLists.txt, "**/CMakeLists.txt", "**/Makefile", "**/*.cmake", cmake.deps/**/* ]
|
||||
|
||||
checkhealth:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ "**/health.lua" ]
|
||||
|
||||
ci:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ .github/actions/**, .github/workflows/**, .github/scripts/** ]
|
||||
@ -14,6 +18,14 @@ column:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ src/nvim/sign* ]
|
||||
|
||||
comment:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ runtime/lua/vim/_comment.lua ]
|
||||
|
||||
defaults:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ runtime/lua/vim/_defaults.lua ]
|
||||
|
||||
diagnostic:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ runtime/lua/vim/diagnostic.lua ]
|
||||
@ -34,6 +46,10 @@ filetype:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ runtime/lua/vim/filetype.lua, runtime/lua/vim/filetype/detect.lua ]
|
||||
|
||||
filesystem:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ runtime/lua/vim/fs.lua ]
|
||||
|
||||
folds:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ src/nvim/fold* ]
|
||||
@ -46,9 +62,9 @@ mouse:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ src/nvim/mouse* ]
|
||||
|
||||
platform:nix:
|
||||
netrw:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: [ contrib/flake.lock, contrib/flake.nix ]
|
||||
- any-glob-to-any-file: [ runtime/autoload/netrw.vim, runtime/plugin/netrwPlugin.vim ]
|
||||
|
||||
snippet:
|
||||
- changed-files:
|
||||
|
24
.github/scripts/reviewers_add.js
vendored
24
.github/scripts/reviewers_add.js
vendored
@ -23,6 +23,10 @@ module.exports = async ({ github, context }) => {
|
||||
reviewers.add("lewis6991");
|
||||
}
|
||||
|
||||
if (labels.includes("comment")) {
|
||||
reviewers.add("echasnovski");
|
||||
}
|
||||
|
||||
if (labels.includes("defaults")) {
|
||||
reviewers.add("gpanders");
|
||||
}
|
||||
@ -35,21 +39,20 @@ module.exports = async ({ github, context }) => {
|
||||
reviewers.add("lewis6991");
|
||||
}
|
||||
|
||||
if (labels.includes("documentation")) {
|
||||
reviewers.add("clason");
|
||||
}
|
||||
|
||||
if (labels.includes("editorconfig")) {
|
||||
reviewers.add("gpanders");
|
||||
}
|
||||
|
||||
if (labels.includes("extmarks")) {
|
||||
if (labels.includes("marks")) {
|
||||
reviewers.add("bfredl");
|
||||
}
|
||||
|
||||
if (labels.includes("filetype")) {
|
||||
reviewers.add("clason");
|
||||
reviewers.add("gpanders");
|
||||
}
|
||||
|
||||
if (labels.includes("inccommand")) {
|
||||
reviewers.add("famiu");
|
||||
}
|
||||
|
||||
if (labels.includes("lsp")) {
|
||||
@ -57,6 +60,10 @@ module.exports = async ({ github, context }) => {
|
||||
reviewers.add("mfussenegger");
|
||||
}
|
||||
|
||||
if (labels.includes("netrw")) {
|
||||
reviewers.add("justinmk");
|
||||
}
|
||||
|
||||
if (labels.includes("options")) {
|
||||
reviewers.add("famiu");
|
||||
}
|
||||
@ -78,10 +85,6 @@ module.exports = async ({ github, context }) => {
|
||||
reviewers.add("famiu");
|
||||
}
|
||||
|
||||
if (labels.includes("test")) {
|
||||
reviewers.add("justinmk");
|
||||
}
|
||||
|
||||
if (labels.includes("treesitter")) {
|
||||
reviewers.add("bfredl");
|
||||
reviewers.add("clason");
|
||||
@ -98,7 +101,6 @@ module.exports = async ({ github, context }) => {
|
||||
}
|
||||
|
||||
if (labels.includes("vim-patch")) {
|
||||
reviewers.add("seandewar");
|
||||
reviewers.add("zeertzjq");
|
||||
}
|
||||
|
||||
|
28
.github/workflows/backport.yml
vendored
28
.github/workflows/backport.yml
vendored
@ -12,25 +12,35 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.BACKPORT_APP }}
|
||||
private-key: ${{ secrets.BACKPORT_KEY }}
|
||||
|
||||
- name: Create backport PR
|
||||
id: backport
|
||||
uses: korthout/backport-action@v2
|
||||
uses: korthout/backport-action@v3
|
||||
with:
|
||||
pull_title: "${pull_title}"
|
||||
label_pattern: "^ci:backport ([^ ]+)$"
|
||||
# https://github.com/korthout/backport-action/pull/399
|
||||
experimental: >
|
||||
{
|
||||
"detect_merge_method": true
|
||||
}
|
||||
github_token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- if: ${{steps.backport.outputs.was_successful == 'true'}}
|
||||
- name: Create failed backport label
|
||||
if: ${{ steps.backport.outputs.was_successful == 'false' }}
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: ${{steps.backport.outputs.created_pull_numbers}},
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['backport']
|
||||
labels: ['needs:backport']
|
||||
})
|
||||
|
||||
- name: Enable automerge
|
||||
if: ${{ steps.backport.outputs.was_successful == 'true' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: gh pr merge --rebase --auto ${{ steps.backport.outputs.created_pull_numbers }}
|
||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -74,7 +74,9 @@ jobs:
|
||||
for d in *; do (cd "$d"; rm -rf ./autom4te.cache; make clean || true; make distclean || true); done
|
||||
|
||||
- name: Re-build bundled dependencies with no network access
|
||||
run: unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
|
||||
run: |
|
||||
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
|
||||
unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
|
||||
|
||||
- name: Build
|
||||
run: make CMAKE_FLAGS="-D CI_BUILD=ON"
|
||||
|
33
.github/workflows/build_dummy.yml
vendored
Normal file
33
.github/workflows/build_dummy.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: build_dummy
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'release-[0-9]+.[0-9]+'
|
||||
# This needs to be an exact complement of `paths` in the build.yml workflow.
|
||||
# This is required to bypass required checks since a required job is always
|
||||
# needed to run.
|
||||
paths-ignore:
|
||||
- '**.cmake'
|
||||
- '**/CMakeLists.txt'
|
||||
- '**/CMakePresets.json'
|
||||
- 'cmake.*/**'
|
||||
- '.github/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
old-cmake:
|
||||
name: Test oldest supported cmake
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- run: echo "success"
|
||||
|
||||
use-existing-src:
|
||||
name: Test USE_EXISTING_SRC_DIR=ON builds with no network access
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "success"
|
7
.github/workflows/docs.yml
vendored
7
.github/workflows/docs.yml
vendored
@ -2,13 +2,6 @@ name: docs
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
paths:
|
||||
- 'src/nvim/api/*.[ch]'
|
||||
- 'src/nvim/eval.lua'
|
||||
- 'runtime/lua/**.lua'
|
||||
- 'runtime/doc/**'
|
||||
- 'scripts/gen_vimdoc.py'
|
||||
- 'scripts/gen_help_html.lua'
|
||||
jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
|
19
.github/workflows/labeler_pr.yml
vendored
19
.github/workflows/labeler_pr.yml
vendored
@ -33,8 +33,25 @@ jobs:
|
||||
- name: "Extract if the PR is a breaking change and add it as label"
|
||||
run: gh pr edit "$PR_NUMBER" --add-label "$(echo "$PR_TITLE" | sed -E 's|[[:alpha:]]+(\(.*\))?!:.*|breaking-change|')" || true
|
||||
|
||||
request-reviewer:
|
||||
target-release:
|
||||
needs: ["changed-files", "type-scope"]
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- if: startsWith(github.base_ref, 'release')
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['target:release']
|
||||
})
|
||||
|
||||
request-reviewer:
|
||||
needs: ["changed-files", "type-scope", "target-release"]
|
||||
permissions:
|
||||
pull-requests: write
|
||||
uses: ./.github/workflows/reviewers_add.yml
|
||||
|
2
.github/workflows/lintcommit.yml
vendored
2
.github/workflows/lintcommit.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: "lintcommit"
|
||||
name: lintcommit
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
16
.github/workflows/lintcommit_dummy.yml
vendored
Normal file
16
.github/workflows/lintcommit_dummy.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Dummy workflow of lintcommit.yml. lintcommit is a required check, but it's
|
||||
# only designed to work on master. Since required checks are always required to
|
||||
# run, we can essentially "skip" the lintcommit on release branches with this
|
||||
# dummy check that automatically passes.
|
||||
name: lintcommit_dummy
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
branches:
|
||||
- 'release-[0-9]+.[0-9]+'
|
||||
jobs:
|
||||
lint-commits:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.draft == false
|
||||
steps:
|
||||
- run: echo "success"
|
46
.github/workflows/notes.md
vendored
46
.github/workflows/notes.md
vendored
@ -32,26 +32,45 @@ ${NVIM_VERSION}
|
||||
3. Extract: `tar xzvf nvim-macos-arm64.tar.gz`
|
||||
4. Run `./nvim-macos-arm64/bin/nvim`
|
||||
|
||||
### Linux (x64)
|
||||
### Linux (x86_64)
|
||||
|
||||
Minimum glibc version to run these releases is 2.31. People requiring releases
|
||||
that work on older glibc versions can find them at
|
||||
https://github.com/neovim/neovim-releases.
|
||||
|
||||
#### AppImage
|
||||
1. Download **nvim.appimage**
|
||||
2. Run `chmod u+x nvim.appimage && ./nvim.appimage`
|
||||
|
||||
1. Download **nvim-linux-x86_64.appimage**
|
||||
2. Run `chmod u+x nvim-linux-x86_64.appimage && ./nvim-linux-x86_64.appimage`
|
||||
- If your system does not have FUSE you can [extract the appimage](https://github.com/AppImage/AppImageKit/wiki/FUSE#type-2-appimage):
|
||||
```
|
||||
./nvim.appimage --appimage-extract
|
||||
./nvim-linux-x86_64.appimage --appimage-extract
|
||||
./squashfs-root/usr/bin/nvim
|
||||
```
|
||||
|
||||
#### Tarball
|
||||
|
||||
1. Download **nvim-linux64.tar.gz**
|
||||
2. Extract: `tar xzvf nvim-linux64.tar.gz`
|
||||
3. Run `./nvim-linux64/bin/nvim`
|
||||
1. Download **nvim-linux-x86_64.tar.gz**
|
||||
2. Extract: `tar xzvf nvim-linux-x86_64.tar.gz`
|
||||
3. Run `./nvim-linux-x86_64/bin/nvim`
|
||||
|
||||
### Linux (arm64)
|
||||
|
||||
#### AppImage
|
||||
|
||||
1. Download **nvim-linux-arm64.appimage**
|
||||
2. Run `chmod u+x nvim-linux-arm64.appimage && ./nvim-linux-arm64.appimage`
|
||||
- If your system does not have FUSE you can [extract the appimage](https://github.com/AppImage/AppImageKit/wiki/FUSE#type-2-appimage):
|
||||
```
|
||||
./nvim-linux-arm64.appimage --appimage-extract
|
||||
./squashfs-root/usr/bin/nvim
|
||||
```
|
||||
|
||||
#### Tarball
|
||||
|
||||
1. Download **nvim-linux-arm64.tar.gz**
|
||||
2. Extract: `tar xzvf nvim-linux-arm64.tar.gz`
|
||||
3. Run `./nvim-linux-arm64/bin/nvim`
|
||||
|
||||
### Other
|
||||
|
||||
@ -60,11 +79,14 @@ https://github.com/neovim/neovim-releases.
|
||||
## SHA256 Checksums
|
||||
|
||||
```
|
||||
${SHA_LINUX_64_TAR}
|
||||
${SHA_APP_IMAGE}
|
||||
${SHA_APP_IMAGE_ZSYNC}
|
||||
${SHA_MACOS_X86_64}
|
||||
${SHA_APPIMAGE_ARM64}
|
||||
${SHA_APPIMAGE_ARM64_ZSYNC}
|
||||
${SHA_LINUX_ARM64_TAR}
|
||||
${SHA_APPIMAGE_X86_64}
|
||||
${SHA_APPIMAGE_X86_64_ZSYNC}
|
||||
${SHA_LINUX_X86_64_TAR}
|
||||
${SHA_MACOS_ARM64}
|
||||
${SHA_WIN_64_ZIP}
|
||||
${SHA_MACOS_X86_64}
|
||||
${SHA_WIN_64_MSI}
|
||||
${SHA_WIN_64_ZIP}
|
||||
```
|
||||
|
6
.github/workflows/optional.yml
vendored
6
.github/workflows/optional.yml
vendored
@ -11,7 +11,7 @@ concurrency:
|
||||
env:
|
||||
INSTALL_PREFIX: ${{ github.workspace }}/nvim-install
|
||||
# Double test timeout since it's running via qemu
|
||||
TEST_TIMEOUT: 2400
|
||||
TEST_TIMEOUT: 3600
|
||||
# TEST_FILE: test/functional/shada
|
||||
# TEST_FILTER: foo
|
||||
|
||||
@ -23,7 +23,7 @@ jobs:
|
||||
matrix:
|
||||
test: [functionaltest, oldtest]
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- run: docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||
- uses: docker://multiarch/ubuntu-core:s390x-focal
|
||||
@ -34,7 +34,7 @@ jobs:
|
||||
bash -c
|
||||
"
|
||||
apt-get -y update &&
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential cmake curl gettext ninja-build locales-all cpanminus git attr libattr1-dev &&
|
||||
time DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential cmake curl gettext ninja-build locales-all cpanminus git attr libattr1-dev xdg-utils &&
|
||||
useradd --create-home qemuci &&
|
||||
chown -R qemuci. . &&
|
||||
runuser -u qemuci -- git clone --depth=1 https://github.com/neovim/neovim.git &&
|
||||
|
80
.github/workflows/release.yml
vendored
80
.github/workflows/release.yml
vendored
@ -39,10 +39,21 @@ jobs:
|
||||
printf "appimage_tag=${APPIMAGE_TAG}\n" >> $GITHUB_OUTPUT
|
||||
|
||||
linux:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: [ ubuntu-20.04, ubuntu-24.04-arm ]
|
||||
include:
|
||||
- runner: ubuntu-20.04
|
||||
arch: x86_64
|
||||
cc: gcc-10
|
||||
- runner: ubuntu-24.04-arm
|
||||
arch: arm64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
env:
|
||||
CC: gcc-10
|
||||
CC: ${{ matrix.cc }}
|
||||
LDAI_NO_APPSTREAM: 1 # skip checking (broken) AppStream metadata for issues
|
||||
outputs:
|
||||
version: ${{ steps.build.outputs.version }}
|
||||
steps:
|
||||
@ -52,22 +63,25 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- run: ./.github/scripts/install_deps.sh
|
||||
- run: echo "CMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}" >> $GITHUB_ENV
|
||||
- if: matrix.arch == 'arm64'
|
||||
run: sudo apt-get update && sudo apt-get install -y libfuse2t64
|
||||
- name: appimage
|
||||
run: ./scripts/genappimage.sh ${{ needs.setup.outputs.appimage_tag }}
|
||||
run: |
|
||||
./scripts/genappimage.sh ${{ needs.setup.outputs.appimage_tag }}
|
||||
- name: tar.gz
|
||||
run: cpack --config build/CPackConfig.cmake -G TGZ
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: appimage
|
||||
name: appimage-${{ matrix.arch }}
|
||||
path: |
|
||||
build/bin/nvim.appimage
|
||||
build/bin/nvim.appimage.zsync
|
||||
build/bin/nvim-linux-${{ matrix.arch }}.appimage
|
||||
build/bin/nvim-linux-${{ matrix.arch }}.appimage.zsync
|
||||
retention-days: 1
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nvim-linux64
|
||||
name: nvim-linux-${{ matrix.arch }}
|
||||
path: |
|
||||
build/nvim-linux64.tar.gz
|
||||
build/nvim-linux-${{ matrix.arch }}.tar.gz
|
||||
retention-days: 1
|
||||
- name: Export version
|
||||
id: build
|
||||
@ -75,15 +89,14 @@ jobs:
|
||||
printf 'version<<END\n' >> $GITHUB_OUTPUT
|
||||
./build/bin/nvim --version | head -n 3 >> $GITHUB_OUTPUT
|
||||
printf 'END\n' >> $GITHUB_OUTPUT
|
||||
|
||||
macos:
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: [ macos-12, macos-14 ]
|
||||
runner: [ macos-13, macos-14 ]
|
||||
include:
|
||||
- runner: macos-12
|
||||
- runner: macos-13
|
||||
arch: x86_64
|
||||
- runner: macos-14
|
||||
arch: arm64
|
||||
@ -104,7 +117,6 @@ jobs:
|
||||
-D CMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }} \
|
||||
-D CMAKE_FIND_FRAMEWORK=NEVER
|
||||
cmake --build .deps
|
||||
|
||||
- name: Build neovim
|
||||
run: |
|
||||
cmake -B build -G Ninja \
|
||||
@ -112,7 +124,6 @@ jobs:
|
||||
-D ENABLE_LIBINTL=OFF \
|
||||
-D CMAKE_FIND_FRAMEWORK=NEVER
|
||||
cmake --build build
|
||||
|
||||
- name: Package
|
||||
run: cpack --config build/CPackConfig.cmake
|
||||
|
||||
@ -187,21 +198,36 @@ jobs:
|
||||
git push origin :stable || true
|
||||
# `sha256sum` outputs <sha> <path>, so we cd into each dir to drop the
|
||||
# containing folder from the output.
|
||||
- name: Generate Linux64 SHA256 checksums
|
||||
- name: Generate Linux x86_64 SHA256 checksums
|
||||
run: |
|
||||
cd ./nvim-linux64
|
||||
sha256sum nvim-linux64.tar.gz > nvim-linux64.tar.gz.sha256sum
|
||||
echo "SHA_LINUX_64_TAR=$(cat nvim-linux64.tar.gz.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate App Image SHA256 checksums
|
||||
cd ./nvim-linux-x86_64
|
||||
sha256sum nvim-linux-x86_64.tar.gz > nvim-linux-x86_64.tar.gz.sha256sum
|
||||
echo "SHA_LINUX_X86_64_TAR=$(cat nvim-linux-x86_64.tar.gz.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate Linux arm64 SHA256 checksums
|
||||
run: |
|
||||
cd ./appimage
|
||||
sha256sum nvim.appimage > nvim.appimage.sha256sum
|
||||
echo "SHA_APP_IMAGE=$(cat nvim.appimage.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate App Image Zsync SHA256 checksums
|
||||
cd ./nvim-linux-arm64
|
||||
sha256sum nvim-linux-arm64.tar.gz > nvim-linux-arm64.tar.gz.sha256sum
|
||||
echo "SHA_LINUX_ARM64_TAR=$(cat nvim-linux-arm64.tar.gz.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate AppImage x64_64 SHA256 checksums
|
||||
run: |
|
||||
cd ./appimage
|
||||
sha256sum nvim.appimage.zsync > nvim.appimage.zsync.sha256sum
|
||||
echo "SHA_APP_IMAGE_ZSYNC=$(cat nvim.appimage.zsync.sha256sum)" >> $GITHUB_ENV
|
||||
cd ./appimage-x86_64
|
||||
sha256sum nvim-linux-x86_64.appimage > nvim-linux-x86_64.appimage.sha256sum
|
||||
echo "SHA_APPIMAGE_X86_64=$(cat nvim-linux-x86_64.appimage.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate AppImage x86_64 Zsync SHA256 checksums
|
||||
run: |
|
||||
cd ./appimage-x86_64
|
||||
sha256sum nvim-linux-x86_64.appimage.zsync > nvim-linux-x86_64.appimage.zsync.sha256sum
|
||||
echo "SHA_APPIMAGE_X86_64_ZSYNC=$(cat nvim-linux-x86_64.appimage.zsync.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate AppImage x64_64 SHA256 checksums
|
||||
run: |
|
||||
cd ./appimage-arm64
|
||||
sha256sum nvim-linux-arm64.appimage > nvim-linux-arm64.appimage.sha256sum
|
||||
echo "SHA_APPIMAGE_ARM64=$(cat nvim-linux-arm64.appimage.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate AppImage arm64 Zsync SHA256 checksums
|
||||
run: |
|
||||
cd ./appimage-arm64
|
||||
sha256sum nvim-linux-arm64.appimage.zsync > nvim-linux-arm64.appimage.zsync.sha256sum
|
||||
echo "SHA_APPIMAGE_ARM64_ZSYNC=$(cat nvim-linux-arm64.appimage.zsync.sha256sum)" >> $GITHUB_ENV
|
||||
- name: Generate macos x86_64 SHA256 checksums
|
||||
run: |
|
||||
cd ./nvim-macos-x86_64
|
||||
@ -226,6 +252,6 @@ jobs:
|
||||
run: |
|
||||
envsubst < "$GITHUB_WORKSPACE/.github/workflows/notes.md" > "$RUNNER_TEMP/notes.md"
|
||||
if [ "$TAG_NAME" != "nightly" ]; then
|
||||
gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux64/* appimage/* nvim-win64/*
|
||||
gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* appimage-x86_64/* appimage-arm64/* nvim-win64/*
|
||||
fi
|
||||
gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux64/* appimage/* nvim-win64/*
|
||||
gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* appimage-x86_64/* appimage-arm64/* nvim-win64/*
|
||||
|
2
.github/workflows/reviewers_add.yml
vendored
2
.github/workflows/reviewers_add.yml
vendored
@ -5,7 +5,7 @@ on:
|
||||
workflow_call:
|
||||
jobs:
|
||||
request-reviewer:
|
||||
if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false
|
||||
if: github.event.pull_request.state == 'open' && github.event.pull_request.draft == false && !endsWith(github.actor, '[bot]')
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
76
.github/workflows/test.yml
vendored
76
.github/workflows/test.yml
vendored
@ -8,8 +8,6 @@ on:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'release-[0-9]+.[0-9]+'
|
||||
paths-ignore:
|
||||
- 'contrib/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
@ -30,7 +28,7 @@ env:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CC: clang
|
||||
@ -80,7 +78,7 @@ jobs:
|
||||
run: cmake --build build --target lintc-uncrustify
|
||||
|
||||
clang-analyzer:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
CC: clang
|
||||
@ -95,18 +93,24 @@ jobs:
|
||||
- run: cmake --build build --target clang-analyzer
|
||||
|
||||
posix:
|
||||
name: ${{ matrix.build.runner }} ${{ matrix.build.flavor }} ${{ matrix.build.cc }} ${{ matrix.test }}
|
||||
name: ${{ matrix.build.os }} ${{ matrix.build.flavor }} ${{ matrix.build.cc }} ${{ matrix.test }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# The `os` field is not needed to differentiate between the different
|
||||
# matrix builds. It is needed to not change the required checks (which
|
||||
# uses jobs names) each time we bump the runner version. It may be
|
||||
# possible to remove if we e.g. start using `-latest` runner versions
|
||||
# or if github introduces a wildcard for required checks in the future.
|
||||
build:
|
||||
[
|
||||
{ runner: ubuntu-22.04, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON },
|
||||
{ runner: ubuntu-22.04, flavor: tsan, cc: clang, flags: -D ENABLE_TSAN=ON },
|
||||
{ runner: ubuntu-22.04, cc: gcc },
|
||||
{ runner: macos-12, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: macos-14, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: ubuntu-22.04, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: tsan, cc: clang, flags: -D ENABLE_TSAN=ON },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: release, cc: gcc, flags: -D CMAKE_BUILD_TYPE=Release },
|
||||
{ runner: ubuntu-24.04-arm, os: ubuntu, flavor: arm, cc: gcc, flags: -D CMAKE_BUILD_TYPE=RelWithDebInfo },
|
||||
{ runner: macos-13, os: macos, flavor: intel, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: macos-15, os: macos, flavor: arm, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
|
||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON },
|
||||
]
|
||||
test: [unittest, functionaltest, oldtest]
|
||||
exclude:
|
||||
@ -142,6 +146,10 @@ jobs:
|
||||
sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log"
|
||||
perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION'
|
||||
|
||||
- name: Remove .git directory
|
||||
if: ${{ matrix.build.os == 'ubuntu' }}
|
||||
run: cmake -E rm -rf -- .git
|
||||
|
||||
- name: Build third-party deps
|
||||
run: |
|
||||
cmake -S cmake.deps --preset ci -D CMAKE_BUILD_TYPE=Debug ${{ matrix.build.deps_flags }}
|
||||
@ -152,9 +160,15 @@ jobs:
|
||||
cmake --preset ci -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.build.flags }}
|
||||
cmake --build build
|
||||
|
||||
- name: ${{ matrix.test }}
|
||||
- if: ${{ matrix.test == 'oldtest' }}
|
||||
name: ${{ matrix.test }}
|
||||
timeout-minutes: 20
|
||||
run: make ${{ matrix.test }}
|
||||
run: make -C test/old/testdir NVIM_PRG=$(realpath build)/bin/nvim
|
||||
|
||||
- if: ${{ matrix.test != 'oldtest' }}
|
||||
name: ${{ matrix.test }}
|
||||
timeout-minutes: 20
|
||||
run: cmake --build build --target ${{ matrix.test }}
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
@ -190,42 +204,8 @@ jobs:
|
||||
windows:
|
||||
uses: ./.github/workflows/test_windows.yml
|
||||
|
||||
# This job tests the following things:
|
||||
# - Check if Release, MinSizeRel and RelWithDebInfo compiles correctly.
|
||||
# - Test the above build types with the GCC compiler specifically.
|
||||
# Empirically the difference in warning levels between GCC and other
|
||||
# compilers is particularly big.
|
||||
# - Test if the build works with multi-config generators. We mostly use
|
||||
# single-config generators so it's nice to have a small sanity check for
|
||||
# multi-config.
|
||||
build-types:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CC: gcc
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/setup
|
||||
|
||||
- name: Build third-party deps
|
||||
run: |
|
||||
cmake -S cmake.deps -B .deps -G "Ninja Multi-Config"
|
||||
cmake --build .deps
|
||||
|
||||
- name: Configure
|
||||
run: cmake --preset ci -G "Ninja Multi-Config"
|
||||
|
||||
- name: Release
|
||||
run: cmake --build build --config Release
|
||||
|
||||
- name: RelWithDebInfo
|
||||
run: cmake --build build --config RelWithDebInfo
|
||||
|
||||
- name: MinSizeRel
|
||||
run: cmake --build build --config MinSizeRel
|
||||
|
||||
with-external-deps:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
CC: gcc
|
||||
|
7
.github/workflows/test_windows.yml
vendored
7
.github/workflows/test_windows.yml
vendored
@ -31,6 +31,13 @@ jobs:
|
||||
cmake --preset ci -D CMAKE_BUILD_TYPE='RelWithDebInfo' ${{ inputs.build_flags }}
|
||||
cmake --build build
|
||||
|
||||
# FIXME(dundargoc): this workaround is needed as the python3 provider
|
||||
# tests suddenly started to become extremely flaky, and this removes the
|
||||
# flakiness for some reason.
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Install test deps
|
||||
run: |
|
||||
$PSNativeCommandArgumentPassing = 'Legacy'
|
||||
|
2
.github/workflows/vim_patches.yml
vendored
2
.github/workflows/vim_patches.yml
vendored
@ -50,6 +50,6 @@ jobs:
|
||||
if: ${{ steps.update-version.outputs.NEW_PATCHES != 0 }}
|
||||
run: |
|
||||
git add -u
|
||||
git commit -m 'docs: update version.c [skip ci]'
|
||||
git commit -m 'docs: update version.c'
|
||||
git push --force https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY} ${VERSION_BRANCH}
|
||||
gh pr create --draft --fill --label vim-patch --base ${GITHUB_REF#refs/heads/} --head ${VERSION_BRANCH} || true
|
||||
|
4
BUILD.md
4
BUILD.md
@ -12,7 +12,7 @@
|
||||
- To build on Windows, see the [Building on Windows](#building-on-windows) section. _MSVC (Visual Studio) is recommended._
|
||||
4. `sudo make install`
|
||||
- Default install location is `/usr/local`
|
||||
- On Debian/Ubuntu, instead of installing files directly with `sudo make install`, you can run `cd build && cpack -G DEB && sudo dpkg -i nvim-linux64.deb` to build DEB-package and install it. This should help ensuring the clean removal of installed files.
|
||||
- On Debian/Ubuntu, instead of `sudo make install`, you can try `cd build && cpack -G DEB && sudo dpkg -i nvim-linux-<arch>.deb` (with `<arch>` either `x86_64` or `arm64`) to build DEB-package and install it. This helps ensure clean removal of installed files. Note: This is an unsupported, "best-effort" feature of the Nvim build.
|
||||
|
||||
**Notes**:
|
||||
- From the repository's root directory, running `make` will download and build all the needed dependencies and put the `nvim` executable in `build/bin`.
|
||||
@ -240,7 +240,7 @@ cmake --build build
|
||||
### How to build without "bundled" dependencies
|
||||
|
||||
1. Manually install the dependencies:
|
||||
- libuv libluv libvterm luajit lua-lpeg lua-mpack msgpack-c tree-sitter tree-sitter-bash tree-sitter-c tree-sitter-lua tree-sitter-markdown tree-sitter-python tree-sitter-query tree-sitter-vim tree-sitter-vimdoc unibilium
|
||||
- libuv libluv libvterm luajit lua-lpeg lua-mpack msgpack-c tree-sitter tree-sitter-c tree-sitter-lua tree-sitter-markdown tree-sitter-query tree-sitter-vim tree-sitter-vimdoc unibilium
|
||||
2. Run CMake:
|
||||
```sh
|
||||
cmake -B build -G Ninja -D CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
@ -39,6 +39,12 @@ include(InstallHelpers)
|
||||
include(PreventInTreeBuilds)
|
||||
include(Util)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# User settings
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
set(DEPS_IGNORE_SHA FALSE)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Variables
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -47,9 +53,6 @@ set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
|
||||
|
||||
file(GLOB DOCFILES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/runtime/doc/*.txt)
|
||||
|
||||
set_directory_properties(PROPERTIES
|
||||
EP_PREFIX "${DEPS_BUILD_DIR}")
|
||||
|
||||
if(NOT CI_BUILD)
|
||||
set(CMAKE_INSTALL_MESSAGE NEVER)
|
||||
endif()
|
||||
@ -142,7 +145,7 @@ endif()
|
||||
# version string, else they are combined with the result of `git describe`.
|
||||
set(NVIM_VERSION_MAJOR 0)
|
||||
set(NVIM_VERSION_MINOR 10)
|
||||
set(NVIM_VERSION_PATCH 0)
|
||||
set(NVIM_VERSION_PATCH 4)
|
||||
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
|
||||
|
||||
# API level
|
||||
@ -241,7 +244,7 @@ add_glob_target(
|
||||
GLOB_DIRS runtime scripts src test
|
||||
GLOB_PAT *.lua
|
||||
TOUCH_STRATEGY PER_DIR)
|
||||
add_dependencies(lintlua-luacheck lua-dev-deps)
|
||||
add_dependencies(lintlua-luacheck lua_dev_deps)
|
||||
|
||||
add_glob_target(
|
||||
TARGET lintlua-stylua
|
||||
@ -300,26 +303,24 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_subdirectory(cmake.packaging)
|
||||
endif()
|
||||
|
||||
get_externalproject_options(uncrustify ${DEPS_IGNORE_SHA})
|
||||
ExternalProject_Add(uncrustify
|
||||
URL https://github.com/uncrustify/uncrustify/archive/uncrustify-0.79.0.tar.gz
|
||||
URL_HASH SHA256=e7afaeabf636b7f0ce4e3e9747b95f7bd939613a8db49579755dddf44fedca5f
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/uncrustify
|
||||
CMAKE_ARGS ${DEPS_CMAKE_ARGS}
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
DOWNLOAD_NO_PROGRESS TRUE)
|
||||
${EXTERNALPROJECT_OPTIONS})
|
||||
|
||||
option(USE_BUNDLED_BUSTED "Use bundled busted" ON)
|
||||
if(USE_BUNDLED_BUSTED)
|
||||
ExternalProject_Add(lua-dev-deps
|
||||
URL https://github.com/neovim/deps/raw/5a1f71cceb24990a0b15fd9a472a5f549f019248/opt/lua-dev-deps.tar.gz
|
||||
URL_HASH SHA256=27db2495f5eddc7fc191701ec9b291486853530c6125609d3197d03481e8d5a2
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lua-dev-deps
|
||||
get_externalproject_options(lua_dev_deps ${DEPS_IGNORE_SHA})
|
||||
ExternalProject_Add(lua_dev_deps
|
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/lua_dev_deps
|
||||
SOURCE_DIR ${DEPS_SHARE_DIR}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
DOWNLOAD_NO_PROGRESS TRUE)
|
||||
${EXTERNALPROJECT_OPTIONS})
|
||||
else()
|
||||
add_custom_target(lua-dev-deps)
|
||||
add_custom_target(lua_dev_deps)
|
||||
endif()
|
||||
|
25
INSTALL.md
25
INSTALL.md
@ -15,9 +15,10 @@ Install from download
|
||||
Downloads are available on the [Releases](https://github.com/neovim/neovim/releases) page.
|
||||
|
||||
* Latest [stable release](https://github.com/neovim/neovim/releases/latest)
|
||||
* [macOS x86](https://github.com/neovim/neovim/releases/latest/download/nvim-macos-x86_64.tar.gz)
|
||||
* [macOS arm](https://github.com/neovim/neovim/releases/latest/download/nvim-macos-arm64.tar.gz)
|
||||
* [Linux](https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz)
|
||||
* [macOS x86_64](https://github.com/neovim/neovim/releases/latest/download/nvim-macos-x86_64.tar.gz)
|
||||
* [macOS arm64](https://github.com/neovim/neovim/releases/latest/download/nvim-macos-arm64.tar.gz)
|
||||
* [Linux x86_64](https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz)
|
||||
* [Linux arm64](https://github.com/neovim/neovim/releases/latest/download/nvim-linux-arm64.tar.gz)
|
||||
* [Windows](https://github.com/neovim/neovim/releases/latest/download/nvim-win64.msi)
|
||||
* Latest [development prerelease](https://github.com/neovim/neovim/releases/nightly)
|
||||
|
||||
@ -55,12 +56,12 @@ Several Neovim GUIs are available from scoop (extras): [scoop.sh/#/apps?q=neovim
|
||||
1. Choose a package (**nvim-winXX.zip**) from the [releases page](https://github.com/neovim/neovim/releases).
|
||||
2. Unzip the package. Any location is fine, administrator privileges are _not_ required.
|
||||
- `$VIMRUNTIME` will be set to that location automatically.
|
||||
3. Double-click `nvim-qt.exe`.
|
||||
3. Run `nvim.exe` from a terminal.
|
||||
|
||||
**Optional** steps:
|
||||
|
||||
- Add the `bin` folder (e.g. `C:\Program Files\nvim\bin`) to your PATH.
|
||||
- This makes it easy to run `nvim` and `nvim-qt` from anywhere.
|
||||
- This makes it easy to run `nvim` from anywhere.
|
||||
- If `:set spell` does not work, create the `C:/Users/foo/AppData/Local/nvim/site/spell` folder.
|
||||
You can then copy your spell files over (for English, located
|
||||
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.spl) and
|
||||
@ -118,24 +119,24 @@ After this step add this to `~/.bashrc`:
|
||||
|
||||
### AppImage ("universal" Linux package)
|
||||
|
||||
The [Releases](https://github.com/neovim/neovim/releases) page provides an [AppImage](https://appimage.org) that runs on most Linux systems. No installation is needed, just download `nvim.appimage` and run it. (It might not work if your Linux distribution is more than 4 years old.)
|
||||
The [Releases](https://github.com/neovim/neovim/releases) page provides an [AppImage](https://appimage.org) that runs on most Linux systems. No installation is needed, just download `nvim-linux-x86_64.appimage` and run it. (It might not work if your Linux distribution is more than 4 years old.) The following instructions assume an `x86_64` architecture; on ARM Linux replace with `arm64`.
|
||||
|
||||
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim.appimage
|
||||
chmod u+x nvim.appimage
|
||||
./nvim.appimage
|
||||
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-86_64.appimage
|
||||
chmod u+x nvim-linux-x86_64.appimage
|
||||
./nvim-linux-x86_64.appimage
|
||||
|
||||
To expose nvim globally:
|
||||
|
||||
mkdir -p /opt/nvim
|
||||
mv nvim.appimage /opt/nvim/nvim
|
||||
mv nvim-linux-x86_64.appimage /opt/nvim/nvim
|
||||
|
||||
And the following line to `~/.bashrc`:
|
||||
|
||||
export PATH="$PATH:/opt/nvim/"
|
||||
|
||||
If the `./nvim.appimage` command fails, try:
|
||||
If the `./nvim-linux-x86_64.appimage` command fails, try:
|
||||
```sh
|
||||
./nvim.appimage --appimage-extract
|
||||
./nvim-linux-x86_64.appimage --appimage-extract
|
||||
./squashfs-root/AppRun --version
|
||||
|
||||
# Optional: exposing nvim globally.
|
||||
|
12
MAINTAIN.md
12
MAINTAIN.md
@ -211,12 +211,12 @@ https://github.com/neovim/neovim-backup
|
||||
* For special-purpose jobs where the runner version doesn't really matter,
|
||||
prefer `-latest` tags so we don't need to manually bump the versions. An
|
||||
example of a special-purpose workflow is `labeler_pr.yml`.
|
||||
* For our testing job `test.yml`, prefer to use the latest stable (i.e.
|
||||
non-beta) version explicitly. Avoid using the `-latest` tags here as it
|
||||
makes it difficult to determine from an unrelated PR if a failure is due
|
||||
to the PR itself or due to GitHub bumping the `-latest` tag without our
|
||||
knowledge. There's also a high risk that automatically bumping the CI
|
||||
versions will fail due to manual work being required from experience.
|
||||
* For our testing job `test.yml`, prefer to use the latest version
|
||||
explicitly. Avoid using the `-latest` tags here as it makes it difficult
|
||||
to determine from an unrelated PR if a failure is due to the PR itself or
|
||||
due to GitHub bumping the `-latest` tag without our knowledge. There's
|
||||
also a high risk that automatically bumping the CI versions will fail due
|
||||
to manual work being required from experience.
|
||||
* For our release job, which is `release.yml`, prefer to use the oldest
|
||||
stable (i.e. non-deprecated) versions available. The reason is that we're
|
||||
trying to produce images that work in the broadest number of environments,
|
||||
|
80
Makefile
80
Makefile
@ -1,3 +1,26 @@
|
||||
ifeq ($(OS),Windows_NT)
|
||||
SHELL := powershell.exe
|
||||
.SHELLFLAGS := -NoProfile -NoLogo
|
||||
MKDIR := @$$null = new-item -itemtype directory -force
|
||||
TOUCH := @$$null = new-item -force
|
||||
RM := remove-item -force
|
||||
CMAKE := cmake
|
||||
CMAKE_GENERATOR := Ninja
|
||||
define rmdir
|
||||
if (Test-Path $1) { remove-item -recurse $1 }
|
||||
endef
|
||||
else
|
||||
MKDIR := mkdir -p
|
||||
TOUCH := touch
|
||||
RM := rm -rf
|
||||
CMAKE := $(shell (command -v cmake3 || command -v cmake || echo cmake))
|
||||
CMAKE_GENERATOR ?= "$(shell (command -v ninja > /dev/null 2>&1 && echo "Ninja") || echo "Unix Makefiles")"
|
||||
GENERATOR_CMD ?= "$(shell (command -v ninja > /dev/null 2>&1 && echo "ninja") || echo "make")"
|
||||
define rmdir
|
||||
rm -rf $1
|
||||
endef
|
||||
endif
|
||||
|
||||
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
MAKEFILE_DIR := $(dir $(MAKEFILE_PATH))
|
||||
|
||||
@ -9,7 +32,6 @@ filter-true = $(strip $(filter-out 1 on ON true TRUE,$1))
|
||||
|
||||
all: nvim
|
||||
|
||||
CMAKE ?= $(shell (command -v cmake3 || echo cmake))
|
||||
CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE)
|
||||
# Extra CMake flags which extend the default set
|
||||
CMAKE_EXTRA_FLAGS ?=
|
||||
@ -37,21 +59,11 @@ else
|
||||
checkprefix: ;
|
||||
endif
|
||||
|
||||
CMAKE_GENERATOR ?= $(shell (command -v ninja > /dev/null 2>&1 && echo "Ninja") || \
|
||||
echo "Unix Makefiles")
|
||||
DEPS_BUILD_DIR ?= .deps
|
||||
DEPS_BUILD_DIR ?= ".deps"
|
||||
ifneq (1,$(words [$(DEPS_BUILD_DIR)]))
|
||||
$(error DEPS_BUILD_DIR must not contain whitespace)
|
||||
endif
|
||||
|
||||
ifeq (,$(BUILD_TOOL))
|
||||
ifeq (Ninja,$(CMAKE_GENERATOR))
|
||||
BUILD_TOOL = ninja
|
||||
else
|
||||
BUILD_TOOL = $(MAKE)
|
||||
endif
|
||||
endif
|
||||
|
||||
DEPS_CMAKE_FLAGS ?=
|
||||
USE_BUNDLED ?=
|
||||
|
||||
@ -61,7 +73,7 @@ endif
|
||||
|
||||
ifneq (,$(findstring functionaltest-lua,$(MAKECMDGOALS)))
|
||||
BUNDLED_LUA_CMAKE_FLAG := -DUSE_BUNDLED_LUA=ON
|
||||
$(shell [ -x $(DEPS_BUILD_DIR)/usr/bin/lua ] || rm build/.ran-*)
|
||||
$(shell [ -x $(DEPS_BUILD_DIR)/usr/bin/lua ] || $(RM) build/.ran-*)
|
||||
endif
|
||||
|
||||
# For use where we want to make sure only a single job is run. This does issue
|
||||
@ -69,34 +81,33 @@ endif
|
||||
SINGLE_MAKE = export MAKEFLAGS= ; $(MAKE)
|
||||
|
||||
nvim: build/.ran-cmake deps
|
||||
$(BUILD_TOOL) -C build
|
||||
$(CMAKE) --build build
|
||||
|
||||
libnvim: build/.ran-cmake deps
|
||||
$(BUILD_TOOL) -C build libnvim
|
||||
$(CMAKE) --build build --target libnvim
|
||||
|
||||
cmake:
|
||||
touch CMakeLists.txt
|
||||
$(TOUCH) CMakeLists.txt
|
||||
$(MAKE) build/.ran-cmake
|
||||
|
||||
build/.ran-cmake: | deps
|
||||
$(CMAKE) -B build -G '$(CMAKE_GENERATOR)' $(CMAKE_FLAGS) $(CMAKE_EXTRA_FLAGS) $(MAKEFILE_DIR)
|
||||
touch $@
|
||||
$(CMAKE) -B build -G $(CMAKE_GENERATOR) $(CMAKE_FLAGS) $(CMAKE_EXTRA_FLAGS) $(MAKEFILE_DIR)
|
||||
$(TOUCH) $@
|
||||
|
||||
deps: | build/.ran-deps-cmake
|
||||
ifeq ($(call filter-true,$(USE_BUNDLED)),)
|
||||
$(BUILD_TOOL) -C $(DEPS_BUILD_DIR)
|
||||
$(CMAKE) --build $(DEPS_BUILD_DIR)
|
||||
endif
|
||||
|
||||
ifeq ($(call filter-true,$(USE_BUNDLED)),)
|
||||
$(DEPS_BUILD_DIR):
|
||||
mkdir -p "$@"
|
||||
$(MKDIR) $@
|
||||
build/.ran-deps-cmake:: $(DEPS_BUILD_DIR)
|
||||
$(CMAKE) -S $(MAKEFILE_DIR)/cmake.deps -B $(DEPS_BUILD_DIR) -G '$(CMAKE_GENERATOR)' \
|
||||
$(BUNDLED_CMAKE_FLAG) $(BUNDLED_LUA_CMAKE_FLAG) $(DEPS_CMAKE_FLAGS)
|
||||
$(CMAKE) -S $(MAKEFILE_DIR)/cmake.deps -B $(DEPS_BUILD_DIR) -G $(CMAKE_GENERATOR) $(BUNDLED_CMAKE_FLAG) $(BUNDLED_LUA_CMAKE_FLAG) $(DEPS_CMAKE_FLAGS)
|
||||
endif
|
||||
build/.ran-deps-cmake::
|
||||
mkdir -p build
|
||||
touch $@
|
||||
$(MKDIR) build
|
||||
$(TOUCH) "$@"
|
||||
|
||||
# TODO: cmake 3.2+ add_custom_target() has a USES_TERMINAL flag.
|
||||
oldtest: | nvim
|
||||
@ -113,7 +124,7 @@ test/old/testdir/%.vim: phony_force nvim
|
||||
$(SINGLE_MAKE) -C test/old/testdir NVIM_PRG=$(NVIM_PRG) SCRIPTS= $(MAKEOVERRIDES) $(patsubst test/old/testdir/%.vim,%,$@)
|
||||
|
||||
functionaltest-lua: | nvim
|
||||
$(BUILD_TOOL) -C build functionaltest
|
||||
$(CMAKE) --build build --target functionaltest
|
||||
|
||||
FORMAT=formatc formatlua format
|
||||
LINT=lintlua lintsh lintc clang-analyzer lintcommit lintdoc lint
|
||||
@ -135,16 +146,19 @@ iwyu: build/.ran-cmake
|
||||
$(CMAKE) --build build
|
||||
|
||||
clean:
|
||||
test -d build && $(BUILD_TOOL) -C build clean || true
|
||||
ifneq ($(wildcard build),)
|
||||
$(CMAKE) --build build --target clean
|
||||
endif
|
||||
$(MAKE) -C test/old/testdir clean
|
||||
$(MAKE) -C runtime/indent clean
|
||||
|
||||
distclean:
|
||||
rm -rf $(DEPS_BUILD_DIR) build
|
||||
$(call rmdir, $(DEPS_BUILD_DIR))
|
||||
$(call rmdir, build)
|
||||
$(MAKE) clean
|
||||
|
||||
install: checkprefix nvim
|
||||
$(BUILD_TOOL) -C build install
|
||||
$(GENERATOR_CMD) -C build install
|
||||
|
||||
appimage:
|
||||
bash scripts/genappimage.sh
|
||||
@ -155,14 +169,4 @@ appimage:
|
||||
appimage-%:
|
||||
bash scripts/genappimage.sh $*
|
||||
|
||||
# Generic pattern rules, allowing for `make build/bin/nvim` etc.
|
||||
# Does not work with "Unix Makefiles".
|
||||
ifeq ($(CMAKE_GENERATOR),Ninja)
|
||||
build/%: phony_force
|
||||
$(BUILD_TOOL) -C build $(patsubst build/%,%,$@)
|
||||
|
||||
$(DEPS_BUILD_DIR)/%: phony_force
|
||||
$(BUILD_TOOL) -C $(DEPS_BUILD_DIR) $(patsubst $(DEPS_BUILD_DIR)/%,%,$@)
|
||||
endif
|
||||
|
||||
.PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST)
|
||||
|
@ -74,25 +74,6 @@ if(APPLE)
|
||||
message(STATUS "Using deployment target ${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
set_directory_properties(PROPERTIES
|
||||
EP_PREFIX "${DEPS_BUILD_DIR}"
|
||||
CMAKE_CONFIGURE_DEPENDS deps.txt)
|
||||
|
||||
file(READ deps.txt DEPENDENCIES)
|
||||
STRING(REGEX REPLACE "\n" ";" DEPENDENCIES "${DEPENDENCIES}")
|
||||
foreach(dep ${DEPENDENCIES})
|
||||
STRING(REGEX REPLACE " " ";" dep "${dep}")
|
||||
list(GET dep 0 name)
|
||||
list(GET dep 1 value)
|
||||
if(NOT ${name})
|
||||
# _URL variables must NOT be set when USE_EXISTING_SRC_DIR is set,
|
||||
# otherwise ExternalProject will try to re-download the sources.
|
||||
if(NOT USE_EXISTING_SRC_DIR)
|
||||
set(${name} ${value})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(USE_BUNDLED_LUAJIT)
|
||||
set(LUA_ENGINE LuaJit)
|
||||
elseif(USE_BUNDLED_LUA)
|
||||
|
@ -28,7 +28,7 @@ function(BuildTSParser)
|
||||
${EXTERNALPROJECT_OPTIONS})
|
||||
endfunction()
|
||||
|
||||
foreach(lang c lua vim vimdoc query python bash)
|
||||
foreach(lang c lua vim vimdoc query)
|
||||
BuildTSParser(LANG ${lang})
|
||||
endforeach()
|
||||
BuildTSParser(LANG markdown CMAKE_FILE MarkdownParserCMakeLists.txt)
|
||||
|
@ -15,15 +15,20 @@ string(REPLACE "#undef HAVE_LONG_LONG_INT" "#define HAVE_LONG_LONG_INT 1" CONFIG
|
||||
string(REPLACE "#undef HAVE_ICONV_H" "#define HAVE_ICONV_H 1" CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
string(REPLACE "#undef HAVE_ICONV" "#define HAVE_ICONV 1" CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
string(REPLACE "#undef ICONV_CONST" "#define ICONV_CONST const" CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
string(REPLACE "#undef uintmax_t" "
|
||||
#if _WIN64
|
||||
# define intmax_t long long
|
||||
# define uintmax_t unsigned long long
|
||||
#elif _WIN32
|
||||
# define intmax_t long
|
||||
# define uintmax_t unsigned long
|
||||
#endif"
|
||||
CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
if(MSVC)
|
||||
string(REPLACE "#undef HAVE_STDINT_H_WITH_UINTMAX" "#define HAVE_STDINT_H_WITH_UINTMAX 1" CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
string(REPLACE "#undef HAVE_STDINT_H" "#define HAVE_STDINT_H 1" CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
else()
|
||||
string(REPLACE "#undef uintmax_t" "
|
||||
#if _WIN64
|
||||
# define intmax_t long long
|
||||
# define uintmax_t unsigned long long
|
||||
#elif _WIN32
|
||||
# define intmax_t long
|
||||
# define uintmax_t unsigned long
|
||||
#endif"
|
||||
CONFIG_CONTENT ${CONFIG_CONTENT})
|
||||
endif()
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gettext-runtime/config.h ${CONFIG_CONTENT})
|
||||
|
||||
set(HAVE_NEWLOCALE 0)
|
||||
|
@ -41,21 +41,22 @@ GETTEXT_SHA256 66415634c6e8c3fa8b71362879ec7575e27da43da562c798a8a2f223e6e47f5c
|
||||
LIBICONV_URL https://github.com/neovim/deps/raw/b9bf36eb31f27e8136d907da38fa23518927737e/opt/libiconv-1.17.tar.gz
|
||||
LIBICONV_SHA256 8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313
|
||||
|
||||
TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.21.0.tar.gz
|
||||
TREESITTER_C_SHA256 6f0f5d1b71cf8ffd8a37fb638c6022fa1245bd630150b538547d52128ce0ea7e
|
||||
TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/v0.21.3.tar.gz
|
||||
TREESITTER_C_SHA256 75a3780df6114cd37496761c4a7c9fd900c78bee3a2707f590d78c0ca3a24368
|
||||
TREESITTER_LUA_URL https://github.com/tree-sitter-grammars/tree-sitter-lua/archive/v0.1.0.tar.gz
|
||||
TREESITTER_LUA_SHA256 230cfcbfa74ed1f7b8149e9a1f34c2efc4c589a71fe0f5dc8560622f8020d722
|
||||
TREESITTER_VIM_URL https://github.com/neovim/tree-sitter-vim/archive/v0.4.0.tar.gz
|
||||
TREESITTER_VIM_SHA256 9f856f8b4a10ab43348550fa2d3cb2846ae3d8e60f45887200549c051c66f9d5
|
||||
TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v2.5.1.tar.gz
|
||||
TREESITTER_VIMDOC_SHA256 063645096504b21603585507c41c6d8718ff3c11b2150c5bfc31e8f3ee9afea3
|
||||
TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.3.0.tar.gz
|
||||
TREESITTER_QUERY_SHA256 f878ff37abcb83250e31a6569e997546f3dbab74dcb26683cb2d613f7568cfc0
|
||||
TREESITTER_PYTHON_URL https://github.com/tree-sitter/tree-sitter-python/archive/v0.21.0.tar.gz
|
||||
TREESITTER_PYTHON_SHA256 720304a603271fa89e4430a14d6a81a023d6d7d1171b1533e49c0ab44f1e1c13
|
||||
TREESITTER_BASH_URL https://github.com/tree-sitter/tree-sitter-bash/archive/v0.21.0.tar.gz
|
||||
TREESITTER_BASH_SHA256 f0515efda839cfede851adb24ac154227fbc0dfb60c6c11595ecfa9087d43ceb
|
||||
TREESITTER_VIMDOC_URL https://github.com/neovim/tree-sitter-vimdoc/archive/v3.0.0.tar.gz
|
||||
TREESITTER_VIMDOC_SHA256 a639bf92bf57bfa1cdc90ca16af27bfaf26a9779064776dd4be34c1ef1453f6c
|
||||
TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/archive/v0.4.0.tar.gz
|
||||
TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e
|
||||
TREESITTER_MARKDOWN_URL https://github.com/MDeiml/tree-sitter-markdown/archive/v0.2.3.tar.gz
|
||||
TREESITTER_MARKDOWN_SHA256 4909d6023643f1afc3ab219585d4035b7403f3a17849782ab803c5f73c8a31d5
|
||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.22.6.tar.gz
|
||||
TREESITTER_SHA256 e2b687f74358ab6404730b7fb1a1ced7ddb3780202d37595ecd7b20a8f41861f
|
||||
|
||||
UNCRUSTIFY_URL https://github.com/uncrustify/uncrustify/archive/uncrustify-0.79.0.tar.gz
|
||||
UNCRUSTIFY_SHA256 e7afaeabf636b7f0ce4e3e9747b95f7bd939613a8db49579755dddf44fedca5f
|
||||
LUA_DEV_DEPS_URL https://github.com/neovim/deps/raw/5a1f71cceb24990a0b15fd9a472a5f549f019248/opt/lua-dev-deps.tar.gz
|
||||
LUA_DEV_DEPS_SHA256 27db2495f5eddc7fc191701ec9b291486853530c6125609d3197d03481e8d5a2
|
||||
|
@ -1,3 +1,7 @@
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm64)
|
||||
endif()
|
||||
|
||||
set(CPACK_PACKAGE_NAME "Neovim")
|
||||
set(CPACK_PACKAGE_VENDOR "neovim.io")
|
||||
set(CPACK_PACKAGE_FILE_NAME "nvim")
|
||||
@ -38,6 +42,7 @@ if(WIN32)
|
||||
# Create start menu and desktop shortcuts
|
||||
set(CPACK_WIX_PROGRAM_MENU_FOLDER "${CPACK_PACKAGE_NAME}")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "nvim" "Neovim")
|
||||
set(CPACK_WIX_INSTALL_SCOPE "perMachine")
|
||||
|
||||
# We use a wix patch to add further options to the installer.
|
||||
# See: https://cmake.org/cmake/help/v3.7/module/CPackWIX.html#variable:CPACK_WIX_PATCH_FILE
|
||||
@ -48,7 +53,7 @@ elseif(APPLE)
|
||||
set(CPACK_GENERATOR TGZ)
|
||||
set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_LIST_DIR}/neovim.icns)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(CPACK_PACKAGE_FILE_NAME "nvim-linux64")
|
||||
set(CPACK_PACKAGE_FILE_NAME "nvim-linux-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(CPACK_GENERATOR TGZ DEB)
|
||||
set(CPACK_DEBIAN_PACKAGE_NAME "Neovim") # required
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Neovim.io") # required
|
||||
|
@ -6,7 +6,7 @@
|
||||
Name='PATH'
|
||||
Action='set'
|
||||
Permanent='no'
|
||||
System='no'
|
||||
System='yes'
|
||||
Part='last'
|
||||
Value='[INSTALL_ROOT]bin'
|
||||
/>
|
||||
|
@ -58,6 +58,32 @@ if(CMAKE_OSX_SYSROOT)
|
||||
set(DEPS_C_COMPILER "${DEPS_C_COMPILER} -isysroot${CMAKE_OSX_SYSROOT}")
|
||||
endif()
|
||||
|
||||
get_filename_component(rootdir ${PROJECT_SOURCE_DIR} NAME)
|
||||
if(${rootdir} MATCHES "cmake.deps")
|
||||
set(depsfile ${PROJECT_SOURCE_DIR}/deps.txt)
|
||||
else()
|
||||
set(depsfile ${PROJECT_SOURCE_DIR}/cmake.deps/deps.txt)
|
||||
endif()
|
||||
|
||||
set_directory_properties(PROPERTIES
|
||||
EP_PREFIX "${DEPS_BUILD_DIR}"
|
||||
CMAKE_CONFIGURE_DEPENDS ${depsfile})
|
||||
|
||||
file(READ ${depsfile} DEPENDENCIES)
|
||||
STRING(REGEX REPLACE "\n" ";" DEPENDENCIES "${DEPENDENCIES}")
|
||||
foreach(dep ${DEPENDENCIES})
|
||||
STRING(REGEX REPLACE " " ";" dep "${dep}")
|
||||
list(GET dep 0 name)
|
||||
list(GET dep 1 value)
|
||||
if(NOT ${name})
|
||||
# _URL variables must NOT be set when USE_EXISTING_SRC_DIR is set,
|
||||
# otherwise ExternalProject will try to re-download the sources.
|
||||
if(NOT USE_EXISTING_SRC_DIR)
|
||||
set(${name} ${value})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
function(get_externalproject_options name DEPS_IGNORE_SHA)
|
||||
string(TOUPPER ${name} name_allcaps)
|
||||
set(url ${${name_allcaps}_URL})
|
||||
|
@ -61,6 +61,7 @@ function(add_glob_target)
|
||||
if(NOT ARG_COMMAND)
|
||||
add_custom_target(${ARG_TARGET})
|
||||
add_custom_command(TARGET ${ARG_TARGET}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${ARG_TARGET} SKIP: ${ARG_COMMAND} not found")
|
||||
return()
|
||||
endif()
|
||||
|
61
contrib/flake.lock
generated
61
contrib/flake.lock
generated
@ -1,61 +0,0 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1713248628,
|
||||
"narHash": "sha256-NLznXB5AOnniUtZsyy/aPWOk8ussTuePp2acb9U+ISA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5672bc9dbf9d88246ddab5ac454e82318d094bb8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
{
|
||||
description = "Neovim flake";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils }:
|
||||
let
|
||||
inherit (builtins)
|
||||
elemAt
|
||||
foldl'
|
||||
mapAttrs
|
||||
match
|
||||
readFile
|
||||
;
|
||||
inherit (nixpkgs.lib)
|
||||
const
|
||||
flip
|
||||
pipe
|
||||
remove
|
||||
splitString
|
||||
toLower
|
||||
;
|
||||
in
|
||||
{
|
||||
overlay = final: prev: {
|
||||
|
||||
neovim = (final.neovim-unwrapped.override {
|
||||
treesitter-parsers = pipe ../cmake.deps/deps.txt [
|
||||
readFile
|
||||
(splitString "\n")
|
||||
(map (match "TREESITTER_([A-Z_]+)_(URL|SHA256)[[:space:]]+([^[:space:]]+)[[:space:]]*"))
|
||||
(remove null)
|
||||
(flip foldl' { }
|
||||
(acc: matches:
|
||||
let
|
||||
lang = toLower (elemAt matches 0);
|
||||
type = toLower (elemAt matches 1);
|
||||
value = elemAt matches 2;
|
||||
in
|
||||
acc // {
|
||||
${lang} = acc.${lang} or { } // {
|
||||
${type} = value;
|
||||
};
|
||||
}))
|
||||
(mapAttrs (const final.fetchurl))
|
||||
(self: self // {
|
||||
markdown = final.stdenv.mkDerivation {
|
||||
inherit (self.markdown) name;
|
||||
src = self.markdown;
|
||||
installPhase = ''
|
||||
mv tree-sitter-markdown $out
|
||||
'';
|
||||
};
|
||||
})
|
||||
];
|
||||
}).overrideAttrs (oa: rec {
|
||||
version = self.shortRev or "dirty";
|
||||
src = ../.;
|
||||
preConfigure = oa.preConfigure or "" + ''
|
||||
sed -i cmake.config/versiondef.h.in -e 's/@NVIM_VERSION_PRERELEASE@/-dev-${version}/'
|
||||
'';
|
||||
nativeBuildInputs = oa.nativeBuildInputs ++ [
|
||||
final.libiconv
|
||||
];
|
||||
});
|
||||
|
||||
# a development binary to help debug issues
|
||||
neovim-debug = let
|
||||
stdenv = if final.stdenv.isLinux then
|
||||
final.llvmPackages_latest.stdenv
|
||||
else
|
||||
final.stdenv;
|
||||
in (final.neovim.override {
|
||||
lua = final.luajit;
|
||||
inherit stdenv;
|
||||
}).overrideAttrs (oa: {
|
||||
|
||||
dontStrip = true;
|
||||
NIX_CFLAGS_COMPILE = " -ggdb -Og";
|
||||
|
||||
cmakeBuildType = "Debug";
|
||||
|
||||
disallowedReferences = [ ];
|
||||
});
|
||||
|
||||
# for neovim developers, beware of the slow binary
|
||||
neovim-developer = let inherit (final.luaPackages) luacheck;
|
||||
in final.neovim-debug.overrideAttrs (oa: {
|
||||
cmakeFlags = oa.cmakeFlags ++ [
|
||||
"-DLUACHECK_PRG=${luacheck}/bin/luacheck"
|
||||
"-DENABLE_LTO=OFF"
|
||||
] ++ final.lib.optionals final.stdenv.isLinux [
|
||||
# https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
|
||||
# https://clang.llvm.org/docs/AddressSanitizer.html#symbolizing-the-reports
|
||||
"-DENABLE_ASAN_UBSAN=ON"
|
||||
];
|
||||
doCheck = final.stdenv.isLinux;
|
||||
});
|
||||
};
|
||||
} // flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
overlays = [ self.overlay ];
|
||||
inherit system;
|
||||
};
|
||||
|
||||
lua = pkgs.lua5_1;
|
||||
|
||||
pythonEnv = pkgs.python3.withPackages (ps: [
|
||||
ps.msgpack
|
||||
]);
|
||||
in {
|
||||
packages = with pkgs; {
|
||||
default = neovim;
|
||||
inherit neovim neovim-debug neovim-developer;
|
||||
};
|
||||
|
||||
checks = {
|
||||
shlint = pkgs.runCommand "shlint" {
|
||||
nativeBuildInputs = [ pkgs.shellcheck ];
|
||||
preferLocalBuild = true;
|
||||
} "make -C ${./..} shlint > $out";
|
||||
};
|
||||
|
||||
# kept for backwards-compatibility
|
||||
defaultPackage = pkgs.neovim;
|
||||
|
||||
devShells = {
|
||||
default = pkgs.neovim-developer.overrideAttrs (oa: {
|
||||
|
||||
buildInputs = with pkgs;
|
||||
oa.buildInputs ++ [
|
||||
lua.pkgs.luacheck
|
||||
sumneko-lua-language-server
|
||||
pythonEnv
|
||||
include-what-you-use # for scripts/check-includes.py
|
||||
jq # jq for scripts/vim-patch.sh -r
|
||||
shellcheck # for `make shlint`
|
||||
];
|
||||
|
||||
nativeBuildInputs = with pkgs;
|
||||
oa.nativeBuildInputs ++ [
|
||||
clang-tools # for clangd to find the correct headers
|
||||
];
|
||||
|
||||
shellHook = oa.shellHook + ''
|
||||
export NVIM_PYTHON_LOG_LEVEL=DEBUG
|
||||
export NVIM_LOG_FILE=/tmp/nvim.log
|
||||
export ASAN_SYMBOLIZER_PATH=${pkgs.llvm_18}/bin/llvm-symbolizer
|
||||
|
||||
# ASAN_OPTIONS=detect_leaks=1
|
||||
export ASAN_OPTIONS="log_path=./test.log:abort_on_error=1"
|
||||
|
||||
# for treesitter functionaltests
|
||||
mkdir -p runtime/parser
|
||||
cp -f ${pkgs.vimPlugins.nvim-treesitter.builtGrammars.c}/parser runtime/parser/c.so
|
||||
'';
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
@ -2820,7 +2820,7 @@ nvim_set_decoration_provider({ns_id}, {opts})
|
||||
Note: this function should not be called often. Rather, the callbacks
|
||||
themselves can be used to throttle unneeded callbacks. the `on_start`
|
||||
callback can return `false` to disable the provider until the next redraw.
|
||||
Similarly, return `false` in `on_win` will skip the `on_lines` calls for
|
||||
Similarly, return `false` in `on_win` will skip the `on_line` calls for
|
||||
that window (but any extmarks set in `on_win` will still be used). A
|
||||
plugin managing multiple sources of decoration should ideally only set one
|
||||
provider, and merge the sources internally. You can use multiple `ns_id`
|
||||
@ -2829,10 +2829,10 @@ nvim_set_decoration_provider({ns_id}, {opts})
|
||||
Note: doing anything other than setting extmarks is considered
|
||||
experimental. Doing things like changing options are not explicitly
|
||||
forbidden, but is likely to have unexpected consequences (such as 100% CPU
|
||||
consumption). doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is
|
||||
consumption). Doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is
|
||||
quite dubious for the moment.
|
||||
|
||||
Note: It is not allowed to remove or update extmarks in 'on_line'
|
||||
Note: It is not allowed to remove or update extmarks in `on_line`
|
||||
callbacks.
|
||||
|
||||
Attributes: ~
|
||||
@ -3496,9 +3496,9 @@ nvim_create_autocmd({event}, {opts}) *nvim_create_autocmd()*
|
||||
• event: (string) name of the triggered event
|
||||
|autocmd-events|
|
||||
• group: (number|nil) autocommand group id, if any
|
||||
• match: (string) expanded value of <amatch>
|
||||
• buf: (number) expanded value of <abuf>
|
||||
• file: (string) expanded value of <afile>
|
||||
• file: (string) <afile> (not expanded to a full path)
|
||||
• match: (string) <amatch> (expanded to a full path)
|
||||
• buf: (number) <abuf>
|
||||
• data: (any) arbitrary data passed from
|
||||
|nvim_exec_autocmds()| *event-data*
|
||||
• command (string) optional: Vim command to execute on event.
|
||||
|
40
runtime/doc/builtin.txt
generated
40
runtime/doc/builtin.txt
generated
@ -2963,8 +2963,8 @@ getregion({pos1}, {pos2} [, {opts}]) *getregion()*
|
||||
difference if the buffer is displayed in a window with
|
||||
different 'virtualedit' or 'list' values.
|
||||
|
||||
Examples: >
|
||||
:xnoremap <CR>
|
||||
Examples: >vim
|
||||
xnoremap <CR>
|
||||
\ <Cmd>echom getregion(
|
||||
\ getpos('v'), getpos('.'), #{ type: mode() })<CR>
|
||||
<
|
||||
@ -3507,7 +3507,7 @@ id({expr}) *id()*
|
||||
Note that `v:_null_string`, `v:_null_list`, `v:_null_dict` and
|
||||
`v:_null_blob` have the same `id()` with different types
|
||||
because they are internally represented as NULL pointers.
|
||||
`id()` returns a hexadecimal representanion of the pointers to
|
||||
`id()` returns a hexadecimal representation of the pointers to
|
||||
the containers (i.e. like `0x994a40`), same as `printf("%p",
|
||||
{expr})`, but it is advised against counting on the exact
|
||||
format of the return value.
|
||||
@ -4597,19 +4597,19 @@ matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}]) *matchbufline()*
|
||||
|
||||
Examples: >vim
|
||||
" Assuming line 3 in buffer 5 contains "a"
|
||||
:echo matchbufline(5, '\<\k\+\>', 3, 3)
|
||||
[{'lnum': 3, 'byteidx': 0, 'text': 'a'}]
|
||||
echo matchbufline(5, '\<\k\+\>', 3, 3)
|
||||
< `[{'lnum': 3, 'byteidx': 0, 'text': 'a'}]` >vim
|
||||
" Assuming line 4 in buffer 10 contains "tik tok"
|
||||
:echo matchbufline(10, '\<\k\+\>', 1, 4)
|
||||
[{'lnum': 4, 'byteidx': 0, 'text': 'tik'}, {'lnum': 4, 'byteidx': 4, 'text': 'tok'}]
|
||||
<
|
||||
echo matchbufline(10, '\<\k\+\>', 1, 4)
|
||||
< `[{'lnum': 4, 'byteidx': 0, 'text': 'tik'}, {'lnum': 4, 'byteidx': 4, 'text': 'tok'}]`
|
||||
|
||||
If {submatch} is present and is v:true, then submatches like
|
||||
"\1", "\2", etc. are also returned. Example: >vim
|
||||
" Assuming line 2 in buffer 2 contains "acd"
|
||||
:echo matchbufline(2, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2, 2
|
||||
echo matchbufline(2, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2, 2
|
||||
\ {'submatches': v:true})
|
||||
[{'lnum': 2, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]
|
||||
< The "submatches" List always contains 9 items. If a submatch
|
||||
< `[{'lnum': 2, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]`
|
||||
The "submatches" List always contains 9 items. If a submatch
|
||||
is not found, then an empty string is returned for that
|
||||
submatch.
|
||||
|
||||
@ -4769,17 +4769,17 @@ matchstrlist({list}, {pat} [, {dict}]) *matchstrlist()*
|
||||
option settings on the pattern.
|
||||
|
||||
Example: >vim
|
||||
:echo matchstrlist(['tik tok'], '\<\k\+\>')
|
||||
[{'idx': 0, 'byteidx': 0, 'text': 'tik'}, {'idx': 0, 'byteidx': 4, 'text': 'tok'}]
|
||||
:echo matchstrlist(['a', 'b'], '\<\k\+\>')
|
||||
[{'idx': 0, 'byteidx': 0, 'text': 'a'}, {'idx': 1, 'byteidx': 0, 'text': 'b'}]
|
||||
<
|
||||
echo matchstrlist(['tik tok'], '\<\k\+\>')
|
||||
< `[{'idx': 0, 'byteidx': 0, 'text': 'tik'}, {'idx': 0, 'byteidx': 4, 'text': 'tok'}]` >vim
|
||||
echo matchstrlist(['a', 'b'], '\<\k\+\>')
|
||||
< `[{'idx': 0, 'byteidx': 0, 'text': 'a'}, {'idx': 1, 'byteidx': 0, 'text': 'b'}]`
|
||||
|
||||
If "submatches" is present and is v:true, then submatches like
|
||||
"\1", "\2", etc. are also returned. Example: >vim
|
||||
:echo matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)',
|
||||
echo matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)',
|
||||
\ #{submatches: v:true})
|
||||
[{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]
|
||||
< The "submatches" List always contains 9 items. If a submatch
|
||||
< `[{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]`
|
||||
The "submatches" List always contains 9 items. If a submatch
|
||||
is not found, then an empty string is returned for that
|
||||
submatch.
|
||||
|
||||
@ -6007,7 +6007,7 @@ screencol() *screencol()*
|
||||
the following mappings: >vim
|
||||
nnoremap <expr> GG ":echom " .. screencol() .. "\n"
|
||||
nnoremap <silent> GG :echom screencol()<CR>
|
||||
noremap GG <Cmd>echom screencol()<Cr>
|
||||
noremap GG <Cmd>echom screencol()<CR>
|
||||
<
|
||||
|
||||
screenpos({winid}, {lnum}, {col}) *screenpos()*
|
||||
|
@ -1220,13 +1220,13 @@ Vim fills these registers with text from yank and delete commands.
|
||||
Numbered register 0 contains the text from the most recent yank command,
|
||||
unless the command specified another register with ["x].
|
||||
Numbered register 1 contains the text deleted by the most recent delete or
|
||||
change command, unless the command specified another register or the text is
|
||||
less than one line (the small delete register is used then). An exception is
|
||||
made for the delete operator with these movement commands: |%|, |(|, |)|, |`|,
|
||||
|/|, |?|, |n|, |N|, |{| and |}|. Register "1 is always used then (this is Vi
|
||||
compatible). The "- register is used as well if the delete is within a line.
|
||||
Note that these characters may be mapped. E.g. |%| is mapped by the matchit
|
||||
plugin.
|
||||
change command (even when the command specified another register), unless the
|
||||
text is less than one line (the small delete register is used then). An
|
||||
exception is made for the delete operator with these movement commands: |%|,
|
||||
|(|, |)|, |`|, |/|, |?|, |n|, |N|, |{| and |}|.
|
||||
Register "1 is always used then (this is Vi compatible). The "- register is
|
||||
used as well if the delete is within a line. Note that these characters may be
|
||||
mapped. E.g. |%| is mapped by the matchit plugin.
|
||||
With each successive deletion or change, Vim shifts the previous contents
|
||||
of register 1 into register 2, 2 into 3, and so forth, losing the previous
|
||||
contents of register 9.
|
||||
|
@ -1623,7 +1623,7 @@ There are three different types of searching:
|
||||
stop-directories are appended to the path (for the 'path' option) or to
|
||||
the filename (for the 'tags' option) with a ';'. If you want several
|
||||
stop-directories separate them with ';'. If you want no stop-directory
|
||||
("search upward till the root directory) just use ';'. >
|
||||
("search upward till the root directory") just use ';'. >
|
||||
/usr/include/sys;/usr
|
||||
< will search in: >
|
||||
/usr/include/sys
|
||||
@ -1636,7 +1636,7 @@ There are three different types of searching:
|
||||
|
||||
If Vim's current path is /u/user_x/work/release and you do >
|
||||
:set path=include;/u/user_x
|
||||
< and then search for a file with |gf| the file is searched in: >
|
||||
< and then search for a file with |gf| the file is searched in: >
|
||||
/u/user_x/work/release/include
|
||||
/u/user_x/work/include
|
||||
/u/user_x/include
|
||||
@ -1648,7 +1648,7 @@ There are three different types of searching:
|
||||
3) Combined up/downward search:
|
||||
If Vim's current path is /u/user_x/work/release and you do >
|
||||
set path=**;/u/user_x
|
||||
< and then search for a file with |gf| the file is searched in: >
|
||||
< and then search for a file with |gf| the file is searched in: >
|
||||
/u/user_x/work/release/**
|
||||
/u/user_x/work/**
|
||||
/u/user_x/**
|
||||
@ -1660,10 +1660,10 @@ There are three different types of searching:
|
||||
|
||||
In the above example you might want to set path to: >
|
||||
:set path=**,/u/user_x/**
|
||||
< This searches:
|
||||
/u/user_x/work/release/** ~
|
||||
/u/user_x/** ~
|
||||
This searches the same directories, but in a different order.
|
||||
< This searches: >
|
||||
/u/user_x/work/release/**
|
||||
/u/user_x/**
|
||||
< This searches the same directories, but in a different order.
|
||||
|
||||
Note that completion for ":find", ":sfind", and ":tabfind" commands do not
|
||||
currently work with 'path' items that contain a URL or use the double star
|
||||
|
@ -293,7 +293,7 @@ loaded by Vim: >
|
||||
ftplugin/sql.vim
|
||||
syntax/sqlinformix.vim
|
||||
indent/sql.vim
|
||||
>
|
||||
<
|
||||
Notice indent/sqlinformix.sql was not loaded. There is no indent file
|
||||
for Informix, Vim loads the default files if the specified files does not
|
||||
exist.
|
||||
@ -349,7 +349,7 @@ The defaults static maps are: >
|
||||
The use of "<C-C>" can be user chosen by using the following in your |init.vim|
|
||||
as it may not work properly on all platforms: >
|
||||
let g:ftplugin_sql_omni_key = '<C-C>'
|
||||
>
|
||||
<
|
||||
The static maps (which are based on the syntax highlight groups) follow this
|
||||
format: >
|
||||
imap <buffer> <C-C>k <C-\><C-O>:call sqlcomplete#Map('sqlKeyword')<CR><C-X><C-O>
|
||||
@ -664,7 +664,7 @@ your |init.vim|: >
|
||||
filetype is changed temporarily to SQL, the sqlcompletion plugin
|
||||
will cache the syntax groups listed in the List specified in this
|
||||
option.
|
||||
>
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
4.5 SQL Maps *sql-completion-maps*
|
||||
|
@ -366,7 +366,7 @@ tag char note action in Normal mode ~
|
||||
or start of putted text
|
||||
|`]| `] 1 cursor to the end of last operated text or
|
||||
end of putted text
|
||||
|``| `` 1 cursor to the position before latest jump
|
||||
|``| "``" 1 cursor to the position before latest jump
|
||||
|`{| `{ 1 cursor to the start of the current paragraph
|
||||
|`}| `} 1 cursor to the end of the current paragraph
|
||||
|a| a 2 append text after the cursor N times
|
||||
@ -397,7 +397,7 @@ tag char note action in Normal mode ~
|
||||
|q| q{0-9a-zA-Z"} record typed characters into named register
|
||||
{0-9a-zA-Z"} (uppercase to append)
|
||||
|q| q (while recording) stops recording
|
||||
|Q| Q replay last recorded macro
|
||||
|Q| Q 2 replay last recorded register
|
||||
|q:| q: edit : command-line in command-line window
|
||||
|q/| q/ edit / command-line in command-line window
|
||||
|q?| q? edit ? command-line in command-line window
|
||||
@ -736,7 +736,7 @@ tag char note action in Normal mode ~
|
||||
search pattern and Visually select it
|
||||
|gP| ["x]gP 2 put the text [from register x] before the
|
||||
cursor N times, leave the cursor after it
|
||||
|gQ| gQ switch to "Ex" mode with Vim editing
|
||||
|gQ| gQ switch to "Ex" mode with Vim editing
|
||||
|gR| gR 2 enter Virtual Replace mode
|
||||
|gT| gT go to the previous tab page
|
||||
|gU| gU{motion} 2 make Nmove text uppercase
|
||||
@ -923,7 +923,6 @@ tag command note action in Visual mode ~
|
||||
|v_O| O move horizontally to other corner of area
|
||||
|v_P| P replace highlighted area with register
|
||||
contents; registers are unchanged
|
||||
Q does not start Ex mode
|
||||
|v_R| R 2 delete the highlighted lines and start
|
||||
insert
|
||||
|v_S| S 2 delete the highlighted lines and start
|
||||
@ -1136,7 +1135,7 @@ tag command action ~
|
||||
|:!!| :!! repeat last ":!" command
|
||||
|:#| :# same as ":number"
|
||||
|:&| :& repeat last ":substitute"
|
||||
|:star| :* use the last Visual area, like :'<,'>
|
||||
|:star| :* use the last Visual area, like ":'<,'>"
|
||||
|:<| :< shift lines one 'shiftwidth' left
|
||||
|:=| := print the last line number
|
||||
|:>| :> shift lines one 'shiftwidth' right
|
||||
|
@ -1927,11 +1927,6 @@ These two commands will keep on asking for lines, until you type a line
|
||||
containing only a ".". Watch out for lines starting with a backslash, see
|
||||
|line-continuation|.
|
||||
|
||||
When in Ex mode (see |-e|) a backslash at the end of the line can be used to
|
||||
insert a NUL character. To be able to have a line ending in a backslash use
|
||||
two backslashes. This means that the number of backslashes is halved, but
|
||||
only at the end of the line.
|
||||
|
||||
NOTE: These commands cannot be used with |:global| or |:vglobal|.
|
||||
":append" and ":insert" don't work properly in between ":if" and
|
||||
":endif", ":for" and ":endfor", ":while" and ":endwhile".
|
||||
|
@ -12,7 +12,7 @@ enhanced LSP tools.
|
||||
|
||||
https://microsoft.github.io/language-server-protocol/
|
||||
|
||||
LSP facilitates features like go-to-definition, find-references, hover,
|
||||
LSP facilitates features like go-to-definition, find references, hover,
|
||||
completion, rename, format, refactor, etc., using semantic whole-project
|
||||
analysis (unlike |ctags|).
|
||||
|
||||
@ -25,26 +25,36 @@ Nvim provides an LSP client, but the servers are provided by third parties.
|
||||
Follow these steps to get LSP features:
|
||||
|
||||
1. Install language servers using your package manager or by following the
|
||||
upstream installation instruction. You can find language servers here:
|
||||
upstream installation instructions. You can find language servers here:
|
||||
https://microsoft.github.io/language-server-protocol/implementors/servers/
|
||||
|
||||
2. Configure the LSP client per language server. See |vim.lsp.start()| or use
|
||||
this minimal example as a guide: >lua
|
||||
2. Use |vim.lsp.start()| to start the LSP server (or attach to an existing
|
||||
one) when a file is opened. Example: >lua
|
||||
-- Create an event handler for the FileType autocommand
|
||||
vim.api.nvim_create_autocmd('FileType', {
|
||||
-- This handler will fire when the buffer's 'filetype' is "python"
|
||||
pattern = 'python',
|
||||
callback = function(ev)
|
||||
vim.lsp.start({
|
||||
name = 'my-server-name',
|
||||
cmd = {'name-of-language-server-executable', '--option', 'arg1', 'arg2'},
|
||||
|
||||
vim.lsp.start({
|
||||
name = 'my-server-name',
|
||||
cmd = {'name-of-language-server-executable'},
|
||||
root_dir = vim.fs.root(0, {'setup.py', 'pyproject.toml'}),
|
||||
-- Set the "root directory" to the parent directory of the file in the
|
||||
-- current buffer (`ev.buf`) that contains either a "setup.py" or a
|
||||
-- "pyproject.toml" file. Files that share a root directory will reuse
|
||||
-- the connection to the same LSP server.
|
||||
root_dir = vim.fs.root(ev.buf, {'setup.py', 'pyproject.toml'}),
|
||||
})
|
||||
end,
|
||||
})
|
||||
<
|
||||
3. Check that the server attached to the buffer: >
|
||||
:lua =vim.lsp.get_clients()
|
||||
3. Check that the buffer is attached to the server: >vim
|
||||
:checkhealth lsp
|
||||
|
||||
4. Configure keymaps and autocmds to use LSP features. See |lsp-config|.
|
||||
4. (Optional) Configure keymaps and autocommands to use LSP features. |lsp-config|
|
||||
|
||||
*lsp-config*
|
||||
*lsp-defaults*
|
||||
When the LSP client starts it enables diagnostics |vim.diagnostic| (see
|
||||
When the Nvim LSP client starts it enables diagnostics |vim.diagnostic| (see
|
||||
|vim.diagnostic.config()| to customize). It also sets various default options,
|
||||
listed below, if (1) the language server supports the functionality and (2)
|
||||
the options are empty or were set by the builtin runtime (ftplugin) files. The
|
||||
@ -57,12 +67,13 @@ options are not restored when the LSP client is stopped or detached.
|
||||
|CTRL-W_}| to utilize the language server.
|
||||
- 'formatexpr' is set to |vim.lsp.formatexpr()|, so you can format lines via
|
||||
|gq| if the language server supports it.
|
||||
- To opt out of this use |gw| instead of gq, or set 'formatexpr' on LspAttach.
|
||||
- To opt out of this use |gw| instead of gq, or clear 'formatexpr' on |LspAttach|.
|
||||
- |K| is mapped to |vim.lsp.buf.hover()| unless |'keywordprg'| is customized or
|
||||
a custom keymap for `K` exists.
|
||||
|
||||
*lsp-defaults-disable*
|
||||
To override the above defaults, set or unset the options on |LspAttach|: >lua
|
||||
To override or delete any of the above defaults, set or unset the options on
|
||||
|LspAttach|: >lua
|
||||
|
||||
vim.api.nvim_create_autocmd('LspAttach', {
|
||||
callback = function(ev)
|
||||
@ -71,7 +82,8 @@ To override the above defaults, set or unset the options on |LspAttach|: >lua
|
||||
vim.keymap.del('n', 'K', { buffer = ev.buf })
|
||||
end,
|
||||
})
|
||||
|
||||
<
|
||||
*lsp-config*
|
||||
To use other LSP features, set keymaps on |LspAttach|. Not all language
|
||||
servers provide the same capabilities. To ensure you only set keymaps if the
|
||||
language server supports a feature, guard keymaps behind capability checks.
|
||||
@ -201,26 +213,26 @@ Each response handler has this signature: >
|
||||
function(err, result, ctx, config)
|
||||
<
|
||||
Parameters: ~
|
||||
- {err} (table|nil) Error info dict, or `nil` if the request
|
||||
completed.
|
||||
- {result} (Result | Params | nil) `result` key of the |lsp-response| or
|
||||
`nil` if the request failed.
|
||||
- {ctx} (table) Table of calling state associated with the
|
||||
handler, with these keys:
|
||||
- {method} (string) |lsp-method| name.
|
||||
- {client_id} (number) |vim.lsp.Client| identifier.
|
||||
- {bufnr} (Buffer) Buffer handle.
|
||||
- {params} (table|nil) Request parameters table.
|
||||
- {version} (number) Document version at time of
|
||||
request. Handlers can compare this to the
|
||||
current document version to check if the
|
||||
response is "stale". See also |b:changedtick|.
|
||||
- {config} (table) Handler-defined configuration table, which allows
|
||||
users to customize handler behavior.
|
||||
For an example, see:
|
||||
|vim.lsp.diagnostic.on_publish_diagnostics()|
|
||||
To configure a particular |lsp-handler|, see:
|
||||
|lsp-handler-configuration|
|
||||
• {err} (`table|nil`) Error info dict, or `nil` if the request
|
||||
completed.
|
||||
• {result} (`Result|Params|nil`) `result` key of the |lsp-response| or
|
||||
`nil` if the request failed.
|
||||
• {ctx} (`table`) Table of calling state associated with the
|
||||
handler, with these keys:
|
||||
• {method} (`string`) |lsp-method| name.
|
||||
• {client_id} (`number`) |vim.lsp.Client| identifier.
|
||||
• {bufnr} (`Buffer`) Buffer handle.
|
||||
• {params} (`table|nil`) Request parameters table.
|
||||
• {version} (`number`) Document version at time of
|
||||
request. Handlers can compare this to the
|
||||
current document version to check if the
|
||||
response is "stale". See also |b:changedtick|.
|
||||
• {config} (`table`) Handler-defined configuration table, which allows
|
||||
users to customize handler behavior.
|
||||
For an example, see:
|
||||
|vim.lsp.diagnostic.on_publish_diagnostics()|
|
||||
To configure a particular |lsp-handler|, see:
|
||||
|lsp-handler-configuration|
|
||||
|
||||
Returns: ~
|
||||
Two values `result, err` where `err` is shaped like an RPC error: >
|
||||
@ -977,7 +989,7 @@ Lua module: vim.lsp.client *lsp-client*
|
||||
if the client supports workspace folders. It
|
||||
can be `null` if the client supports workspace
|
||||
folders but none are configured.
|
||||
• {root_dir} (`string`)
|
||||
• {root_dir} (`string?`)
|
||||
• {attached_buffers} (`table<integer,true>`)
|
||||
• {commands} (`table<string,fun(command: lsp.Command, ctx: table)>`)
|
||||
Table of command name to function which is
|
||||
@ -1460,7 +1472,7 @@ get_namespace({client_id}, {is_pull})
|
||||
client. Defaults to push
|
||||
|
||||
*vim.lsp.diagnostic.on_diagnostic()*
|
||||
on_diagnostic({_}, {result}, {ctx}, {config})
|
||||
on_diagnostic({error}, {result}, {ctx}, {config})
|
||||
|lsp-handler| for the method "textDocument/diagnostic"
|
||||
|
||||
See |vim.diagnostic.config()| for configuration options. Handler-specific
|
||||
@ -1485,6 +1497,7 @@ on_diagnostic({_}, {result}, {ctx}, {config})
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {error} (`lsp.ResponseError?`)
|
||||
• {result} (`lsp.DocumentDiagnosticReport`)
|
||||
• {ctx} (`lsp.HandlerContext`)
|
||||
• {config} (`vim.diagnostic.Opts`) Configuration table (see
|
||||
@ -1634,7 +1647,7 @@ is_enabled({filter}) *vim.lsp.inlay_hint.is_enabled()*
|
||||
Query whether inlay hint is enabled in the {filter}ed scope
|
||||
|
||||
Parameters: ~
|
||||
• {filter} (`table`) Optional filters |kwargs|, or `nil` for all.
|
||||
• {filter} (`table?`) Optional filters |kwargs|, or `nil` for all.
|
||||
• {bufnr} (`integer?`) Buffer number, or 0 for current
|
||||
buffer, or nil for all.
|
||||
|
||||
|
@ -680,8 +680,8 @@ vim.diff({a}, {b}, {opts}) *vim.diff()*
|
||||
Parameters: ~
|
||||
• {a} (`string`) First string to compare
|
||||
• {b} (`string`) Second string to compare
|
||||
• {opts} (`table`) Optional parameters:
|
||||
• {on_hunk}
|
||||
• {opts} (`table?`) Optional parameters:
|
||||
• {on_hunk}?
|
||||
(`fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer`)
|
||||
Invoked for each hunk in the diff. Return a negative number
|
||||
to cancel the callback for any remaining hunks. Arguments:
|
||||
@ -689,33 +689,33 @@ vim.diff({a}, {b}, {opts}) *vim.diff()*
|
||||
• `count_a` (`integer`): Hunk size in {a}.
|
||||
• `start_b` (`integer`): Start line of hunk in {b}.
|
||||
• `count_b` (`integer`): Hunk size in {b}.
|
||||
• {result_type} (`'unified'|'indices'`, default: `'unified'`)
|
||||
• {result_type}? (`'unified'|'indices'`, default: `'unified'`)
|
||||
Form of the returned diff:
|
||||
• `unified`: String in unified format.
|
||||
• `indices`: Array of hunk locations. Note: This option is
|
||||
ignored if `on_hunk` is used.
|
||||
• {linematch} (`boolean|integer`) Run linematch on the
|
||||
• {linematch}? (`boolean|integer`) Run linematch on the
|
||||
resulting hunks from xdiff. When integer, only hunks upto
|
||||
this size in lines are run through linematch. Requires
|
||||
`result_type = indices`, ignored otherwise.
|
||||
• {algorithm} (`'myers'|'minimal'|'patience'|'histogram'`,
|
||||
• {algorithm}? (`'myers'|'minimal'|'patience'|'histogram'`,
|
||||
default: `'myers'`) Diff algorithm to use. Values:
|
||||
• `myers`: the default algorithm
|
||||
• `minimal`: spend extra time to generate the smallest
|
||||
possible diff
|
||||
• `patience`: patience diff algorithm
|
||||
• `histogram`: histogram diff algorithm
|
||||
• {ctxlen} (`integer`) Context length
|
||||
• {interhunkctxlen} (`integer`) Inter hunk context length
|
||||
• {ignore_whitespace} (`boolean`) Ignore whitespace
|
||||
• {ignore_whitespace_change} (`boolean`) Ignore whitespace
|
||||
• {ctxlen}? (`integer`) Context length
|
||||
• {interhunkctxlen}? (`integer`) Inter hunk context length
|
||||
• {ignore_whitespace}? (`boolean`) Ignore whitespace
|
||||
• {ignore_whitespace_change}? (`boolean`) Ignore whitespace
|
||||
change
|
||||
• {ignore_whitespace_change_at_eol} (`boolean`) Ignore
|
||||
• {ignore_whitespace_change_at_eol}? (`boolean`) Ignore
|
||||
whitespace change at end-of-line.
|
||||
• {ignore_cr_at_eol} (`boolean`) Ignore carriage return at
|
||||
• {ignore_cr_at_eol}? (`boolean`) Ignore carriage return at
|
||||
end-of-line
|
||||
• {ignore_blank_lines} (`boolean`) Ignore blank lines
|
||||
• {indent_heuristic} (`boolean`) Use the indent heuristic for
|
||||
• {ignore_blank_lines}? (`boolean`) Ignore blank lines
|
||||
• {indent_heuristic}? (`boolean`) Use the indent heuristic for
|
||||
the internal diff library.
|
||||
|
||||
Return: ~
|
||||
@ -1426,12 +1426,9 @@ Option:remove({value}) *vim.opt:remove()*
|
||||
• {value} (`string`) Value to remove
|
||||
|
||||
vim.bo[{bufnr}] *vim.bo*
|
||||
Get or set buffer-scoped |options| for the buffer with number {bufnr}. If
|
||||
{bufnr} is omitted then the current buffer is used. Invalid {bufnr} or key
|
||||
is an error.
|
||||
|
||||
Note: this is equivalent to `:setlocal` for |global-local| options and
|
||||
`:set` otherwise.
|
||||
Get or set buffer-scoped |options| for the buffer with number {bufnr}.
|
||||
Like `:setlocal`. If {bufnr} is omitted then the current buffer is used.
|
||||
Invalid {bufnr} or key is an error.
|
||||
|
||||
Example: >lua
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
@ -1646,12 +1643,15 @@ vim.on_key({fn}, {ns_id}) *vim.on_key()*
|
||||
• {fn} will not be cleared by |nvim_buf_clear_namespace()|
|
||||
|
||||
Parameters: ~
|
||||
• {fn} (`fun(key: string, typed: string)?`) Function invoked on
|
||||
every key press. |i_CTRL-V| {key} is the key after mappings
|
||||
have been applied, and {typed} is the key(s) before mappings
|
||||
are applied, which may be empty if {key} is produced by
|
||||
non-typed keys. When {fn} is nil and {ns_id} is specified,
|
||||
the callback associated with namespace {ns_id} is removed.
|
||||
• {fn} (`fun(key: string, typed: string)?`) Function invoked for
|
||||
every input key, after mappings have been applied but before
|
||||
further processing. Arguments {key} and {typed} are raw
|
||||
keycodes, where {key} is the key after mappings are applied,
|
||||
and {typed} is the key(s) before mappings are applied.
|
||||
{typed} may be empty if {key} is produced by non-typed key(s)
|
||||
or by the same typed key(s) that produced a previous {key}.
|
||||
When {fn} is `nil` and {ns_id} is specified, the callback
|
||||
associated with namespace {ns_id} is removed.
|
||||
• {ns_id} (`integer?`) Namespace ID. If nil or 0, generates and returns
|
||||
a new |nvim_create_namespace()| id.
|
||||
|
||||
@ -1659,6 +1659,9 @@ vim.on_key({fn}, {ns_id}) *vim.on_key()*
|
||||
(`integer`) Namespace id associated with {fn}. Or count of all
|
||||
callbacks if on_key() is called without arguments.
|
||||
|
||||
See also: ~
|
||||
• |keytrans()|
|
||||
|
||||
vim.paste({lines}, {phase}) *vim.paste()*
|
||||
Paste handler, invoked by |nvim_paste()| when a conforming UI (such as the
|
||||
|TUI|) pastes text into the editor.
|
||||
@ -3012,7 +3015,10 @@ vim.fs.parents({start}) *vim.fs.parents()*
|
||||
|
||||
vim.fs.root({source}, {marker}) *vim.fs.root()*
|
||||
Find the first parent directory containing a specific "marker", relative
|
||||
to a buffer's directory.
|
||||
to a file path or buffer.
|
||||
|
||||
If the buffer is unnamed (has no backing file) or has a non-empty
|
||||
'buftype' then the search begins from Nvim's |current-directory|.
|
||||
|
||||
Example: >lua
|
||||
-- Find the root of a Python project, starting from file 'main.py'
|
||||
@ -3029,7 +3035,8 @@ vim.fs.root({source}, {marker}) *vim.fs.root()*
|
||||
|
||||
Parameters: ~
|
||||
• {source} (`integer|string`) Buffer number (0 for current buffer) or
|
||||
file path to begin the search from.
|
||||
file path (absolute or relative to the |current-directory|)
|
||||
to begin the search from.
|
||||
• {marker} (`string|string[]|fun(name: string, path: string): boolean`)
|
||||
A marker, or list of markers, to search for. If a function,
|
||||
the function is called for each evaluated item and should
|
||||
@ -3085,7 +3092,7 @@ In addition, its regex-like interface is available as |vim.re|
|
||||
|
||||
|
||||
|
||||
Pattern:match({subject}, {init}) *Pattern:match()*
|
||||
Pattern:match({subject}, {init}, {...}) *Pattern:match()*
|
||||
Matches the given `pattern` against the `subject` string. If the match
|
||||
succeeds, returns the index in the subject of the first character after
|
||||
the match, or the captured values (if the pattern captured any value). An
|
||||
@ -3108,9 +3115,10 @@ Pattern:match({subject}, {init}) *Pattern:match()*
|
||||
Parameters: ~
|
||||
• {subject} (`string`)
|
||||
• {init} (`integer?`)
|
||||
• {...} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`integer|vim.lpeg.Capture?`)
|
||||
(`any`) ...
|
||||
|
||||
vim.lpeg.B({pattern}) *vim.lpeg.B()*
|
||||
Returns a pattern that matches only if the input string at the current
|
||||
@ -3120,7 +3128,7 @@ vim.lpeg.B({pattern}) *vim.lpeg.B()*
|
||||
or failure.
|
||||
|
||||
Parameters: ~
|
||||
• {pattern} (`vim.lpeg.Pattern`)
|
||||
• {pattern} (`vim.lpeg.Pattern|string|integer|boolean|table`)
|
||||
|
||||
Return: ~
|
||||
(`vim.lpeg.Pattern`)
|
||||
@ -3144,7 +3152,7 @@ vim.lpeg.C({patt}) *vim.lpeg.C()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {patt} (`vim.lpeg.Pattern`)
|
||||
• {patt} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
|
||||
Return: ~
|
||||
(`vim.lpeg.Capture`)
|
||||
@ -3195,11 +3203,11 @@ vim.lpeg.Cf({patt}, {func}) *vim.lpeg.Cf()*
|
||||
This capture assumes that `patt` should produce at least one capture with
|
||||
at least one value (of any type), which becomes the initial value of an
|
||||
accumulator. (If you need a specific initial value, you may prefix a
|
||||
constant captureto `patt`.) For each subsequent capture, LPeg calls `func`
|
||||
with this accumulator as the first argument and all values produced by the
|
||||
capture as extra arguments; the first result from this call becomes the
|
||||
new value for the accumulator. The final value of the accumulator becomes
|
||||
the captured value.
|
||||
constant capture to `patt`.) For each subsequent capture, LPeg calls
|
||||
`func` with this accumulator as the first argument and all values produced
|
||||
by the capture as extra arguments; the first result from this call becomes
|
||||
the new value for the accumulator. The final value of the accumulator
|
||||
becomes the captured value.
|
||||
|
||||
Example: >lua
|
||||
local number = lpeg.R('09') ^ 1 / tonumber
|
||||
@ -3210,7 +3218,7 @@ vim.lpeg.Cf({patt}, {func}) *vim.lpeg.Cf()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {patt} (`vim.lpeg.Pattern`)
|
||||
• {patt} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
• {func} (`fun(acc, newvalue)`)
|
||||
|
||||
Return: ~
|
||||
@ -3222,7 +3230,7 @@ vim.lpeg.Cg({patt}, {name}) *vim.lpeg.Cg()*
|
||||
with the given name (which can be any non-nil Lua value).
|
||||
|
||||
Parameters: ~
|
||||
• {patt} (`vim.lpeg.Pattern`)
|
||||
• {patt} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
• {name} (`string?`)
|
||||
|
||||
Return: ~
|
||||
@ -3245,8 +3253,9 @@ vim.lpeg.Cmt({patt}, {fn}) *vim.lpeg.Cmt()*
|
||||
function become the values produced by the capture.
|
||||
|
||||
Parameters: ~
|
||||
• {patt} (`vim.lpeg.Pattern`)
|
||||
• {fn} (`function`)
|
||||
• {patt} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
• {fn} (`fun(s: string, i: integer, ...: any)`) (position:
|
||||
boolean|integer, ...: any)
|
||||
|
||||
Return: ~
|
||||
(`vim.lpeg.Capture`)
|
||||
@ -3285,7 +3294,7 @@ vim.lpeg.Cs({patt}) *vim.lpeg.Cs()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {patt} (`vim.lpeg.Pattern`)
|
||||
• {patt} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
|
||||
Return: ~
|
||||
(`vim.lpeg.Capture`)
|
||||
@ -3298,7 +3307,7 @@ vim.lpeg.Ct({patt}) *vim.lpeg.Ct()*
|
||||
the group name as its key. The captured value is only the table.
|
||||
|
||||
Parameters: ~
|
||||
• {patt} (`vim.lpeg.Pattern|''`)
|
||||
• {patt} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
|
||||
Return: ~
|
||||
(`vim.lpeg.Capture`)
|
||||
@ -3333,7 +3342,7 @@ vim.lpeg.locale({tab}) *vim.lpeg.locale()*
|
||||
Return: ~
|
||||
(`vim.lpeg.Locale`)
|
||||
|
||||
vim.lpeg.match({pattern}, {subject}, {init}) *vim.lpeg.match()*
|
||||
vim.lpeg.match({pattern}, {subject}, {init}, {...}) *vim.lpeg.match()*
|
||||
Matches the given `pattern` against the `subject` string. If the match
|
||||
succeeds, returns the index in the subject of the first character after
|
||||
the match, or the captured values (if the pattern captured any value). An
|
||||
@ -3354,12 +3363,13 @@ vim.lpeg.match({pattern}, {subject}, {init}) *vim.lpeg.match()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {pattern} (`vim.lpeg.Pattern`)
|
||||
• {pattern} (`vim.lpeg.Pattern|string|integer|boolean|table|function`)
|
||||
• {subject} (`string`)
|
||||
• {init} (`integer?`)
|
||||
• {...} (`any`)
|
||||
|
||||
Return: ~
|
||||
(`integer|vim.lpeg.Capture?`)
|
||||
(`any`) ...
|
||||
|
||||
vim.lpeg.P({value}) *vim.lpeg.P()*
|
||||
Converts the given value into a proper pattern. The following rules are
|
||||
@ -3453,7 +3463,7 @@ vim.lpeg.V({v}) *vim.lpeg.V()*
|
||||
<
|
||||
|
||||
Parameters: ~
|
||||
• {v} (`string|integer`)
|
||||
• {v} (`boolean|string|number|function|table|thread|userdata|lightuserdata`)
|
||||
|
||||
Return: ~
|
||||
(`vim.lpeg.Pattern`)
|
||||
@ -4385,8 +4395,9 @@ vim.text.hexdecode({enc}) *vim.text.hexdecode()*
|
||||
Parameters: ~
|
||||
• {enc} (`string`) String to decode
|
||||
|
||||
Return: ~
|
||||
(`string`) Decoded string
|
||||
Return (multiple): ~
|
||||
(`string?`) Decoded string
|
||||
(`string?`) Error message, if any
|
||||
|
||||
vim.text.hexencode({str}) *vim.text.hexencode()*
|
||||
Hex encode a string.
|
||||
@ -4402,7 +4413,7 @@ vim.text.hexencode({str}) *vim.text.hexencode()*
|
||||
Lua module: tohtml *vim.tohtml*
|
||||
|
||||
|
||||
:TOhtml {file} *:TOhtml*
|
||||
:[range]TOhtml {file} *:TOhtml*
|
||||
Converts the buffer shown in the current window to HTML, opens the generated
|
||||
HTML in a new split window, and saves its contents to {file}. If {file} is not
|
||||
given, a temporary file (created by |tempname()|) is used.
|
||||
@ -4424,6 +4435,8 @@ tohtml.tohtml({winid}, {opt}) *tohtml.tohtml.tohtml()*
|
||||
• {width}? (`integer`, default: 'textwidth' if non-zero or
|
||||
window width otherwise) Width used for items which are
|
||||
either right aligned or repeat a character infinitely.
|
||||
• {range}? (`integer[]`, default: entire buffer) Range of
|
||||
rows to use.
|
||||
|
||||
Return: ~
|
||||
(`string[]`)
|
||||
|
@ -1380,11 +1380,13 @@ completion can be enabled:
|
||||
|
||||
-complete=arglist file names in argument list
|
||||
-complete=augroup autocmd groups
|
||||
-complete=breakpoint |:breakadd| suboptions
|
||||
-complete=buffer buffer names
|
||||
-complete=behave :behave suboptions
|
||||
-complete=color color schemes
|
||||
-complete=command Ex command (and arguments)
|
||||
-complete=compiler compilers
|
||||
-complete=diff_buffer diff buffer names
|
||||
-complete=dir directory names
|
||||
-complete=environment environment variable names
|
||||
-complete=event autocommand events
|
||||
@ -1395,7 +1397,7 @@ completion can be enabled:
|
||||
-complete=function function name
|
||||
-complete=help help subjects
|
||||
-complete=highlight highlight groups
|
||||
-complete=history :history suboptions
|
||||
-complete=history |:history| suboptions
|
||||
-complete=keymap keyboard mappings
|
||||
-complete=locale locale names (as output of locale -a)
|
||||
-complete=lua Lua expression |:lua|
|
||||
@ -1405,6 +1407,8 @@ completion can be enabled:
|
||||
-complete=messages |:messages| suboptions
|
||||
-complete=option options
|
||||
-complete=packadd optional package |pack-add| names
|
||||
-complete=runtime file and directory names in |'runtimepath'|
|
||||
-complete=scriptnames sourced script names
|
||||
-complete=shellcmd Shell command
|
||||
-complete=sign |:sign| suboptions
|
||||
-complete=syntax syntax file names |'syntax'|
|
||||
|
@ -354,11 +354,11 @@ gg Goto line [count], default first line, on the first
|
||||
See also 'startofline' option.
|
||||
|
||||
:[range]go[to] [count] *:go* *:goto* *go*
|
||||
[count]go Go to [count] byte in the buffer. Default [count] is
|
||||
one, start of the file. When giving [range], the
|
||||
last number in it used as the byte count. End-of-line
|
||||
characters are counted depending on the current
|
||||
'fileformat' setting.
|
||||
[count]go Go to [count] byte in the buffer. |exclusive| motion.
|
||||
Default [count] is one, start of the file. When
|
||||
giving [range], the last number in it used as the byte
|
||||
count. End-of-line characters are counted depending
|
||||
on the current 'fileformat' setting.
|
||||
Also see the |line2byte()| function, and the 'o'
|
||||
option in 'statusline'.
|
||||
|
||||
|
@ -349,8 +349,8 @@ The following new features were added.
|
||||
|default-autocmds|
|
||||
|
||||
• Treesitter:
|
||||
• Bundled parsers and queries (highlight, folds) for Markdown, Python, and
|
||||
Bash.
|
||||
• Bundled parsers and queries (highlight, folds) for Markdown (used for LSP
|
||||
hover).
|
||||
• |:InspectTree| shows root nodes.
|
||||
• |:InspectTree| now supports |folding|.
|
||||
• |:InspectTree| shows node ranges in 0-based instead of 1-based indexing.
|
||||
|
@ -1092,7 +1092,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
applying 'breakindent', even if the resulting
|
||||
text should normally be narrower. This prevents
|
||||
text indented almost to the right window border
|
||||
occupying lot of vertical space when broken.
|
||||
occupying lots of vertical space when broken.
|
||||
(default: 20)
|
||||
shift:{n} After applying 'breakindent', the wrapped line's
|
||||
beginning will be shifted by the given number of
|
||||
@ -3439,7 +3439,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
in Insert mode as specified with the 'indentkeys' option.
|
||||
When this option is not empty, it overrules the 'cindent' and
|
||||
'smartindent' indenting. When 'lisp' is set, this option is
|
||||
is only used when 'lispoptions' contains "expr:1".
|
||||
only used when 'lispoptions' contains "expr:1".
|
||||
The expression is evaluated with |v:lnum| set to the line number for
|
||||
which the indent is to be computed. The cursor is also in this line
|
||||
when the expression is evaluated (but it may be moved around).
|
||||
@ -3611,7 +3611,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
Otherwise only one space is inserted.
|
||||
|
||||
*'jumpoptions'* *'jop'*
|
||||
'jumpoptions' 'jop' string (default "")
|
||||
'jumpoptions' 'jop' string (default "clean")
|
||||
global
|
||||
List of words that change the behavior of the |jumplist|.
|
||||
stack Make the jumplist behave like the tagstack.
|
||||
@ -3624,6 +3624,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
|alternate-file| or using |mark-motions| try to
|
||||
restore the |mark-view| in which the action occurred.
|
||||
|
||||
clean Remove unloaded buffers from the jumplist.
|
||||
EXPERIMENTAL: this flag may change in the future.
|
||||
|
||||
*'keymap'* *'kmp'*
|
||||
'keymap' 'kmp' string (default "")
|
||||
local to buffer
|
||||
@ -3688,7 +3691,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
part can be in one of two forms:
|
||||
1. A list of pairs. Each pair is a "from" character immediately
|
||||
followed by the "to" character. Examples: "aA", "aAbBcC".
|
||||
2. A list of "from" characters, a semi-colon and a list of "to"
|
||||
2. A list of "from" characters, a semicolon and a list of "to"
|
||||
characters. Example: "abc;ABC"
|
||||
Example: "aA,fgh;FGH,cCdDeE"
|
||||
Special characters need to be preceded with a backslash. These are
|
||||
@ -3756,7 +3759,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
update use |:redraw|.
|
||||
This may occasionally cause display errors. It is only meant to be set
|
||||
temporarily when performing an operation where redrawing may cause
|
||||
flickering or cause a slow down.
|
||||
flickering or cause a slowdown.
|
||||
|
||||
*'linebreak'* *'lbr'* *'nolinebreak'* *'nolbr'*
|
||||
'linebreak' 'lbr' boolean (default off)
|
||||
@ -3834,6 +3837,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
between tabs and spaces and for trailing blanks. Further changed by
|
||||
the 'listchars' option.
|
||||
|
||||
When 'listchars' does not contain "tab" field, tabs are shown as "^I"
|
||||
or "<09>", like how unprintable characters are displayed.
|
||||
|
||||
The cursor is displayed at the start of the space a Tab character
|
||||
occupies, not at the end as usual in Normal mode. To get this cursor
|
||||
position while displaying Tabs with spaces, use: >vim
|
||||
@ -4582,7 +4588,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
set path+=
|
||||
< To use an environment variable, you probably need to replace the
|
||||
separator. Here is an example to append $INCL, in which directory
|
||||
names are separated with a semi-colon: >vim
|
||||
names are separated with a semicolon: >vim
|
||||
let &path = &path .. "," .. substitute($INCL, ';', ',', 'g')
|
||||
< Replace the ';' with a ':' or whatever separator is used. Note that
|
||||
this doesn't work when $INCL contains a comma or white space.
|
||||
@ -5442,7 +5448,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
'shortmess' 'shm' string (default "ltToOCF")
|
||||
global
|
||||
This option helps to avoid all the |hit-enter| prompts caused by file
|
||||
messages, for example with CTRL-G, and to avoid some other messages.
|
||||
messages, for example with CTRL-G, and to avoid some other messages.
|
||||
It is a list of flags:
|
||||
flag meaning when present ~
|
||||
l use "999L, 888B" instead of "999 lines, 888 bytes" *shm-l*
|
||||
@ -5847,7 +5853,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
minus two.
|
||||
|
||||
timeout:{millisec} Limit the time searching for suggestions to
|
||||
{millisec} milli seconds. Applies to the following
|
||||
{millisec} milliseconds. Applies to the following
|
||||
methods. When omitted the limit is 5000. When
|
||||
negative there is no limit.
|
||||
|
||||
|
@ -12,11 +12,12 @@ Support *support*
|
||||
Supported platforms *supported-platforms*
|
||||
|
||||
`System` `Tier` `Versions` `Tested versions`
|
||||
Linux 1 >= 2.6.32, glibc >= 2.12 Ubuntu 22.04
|
||||
macOS (Intel) 1 >= 11 macOS 12
|
||||
macOS (M1) 2 >= 11 macOS 14
|
||||
Linux (x86_64) 1 >= 2.6.32, glibc >= 2.12 Ubuntu 24.04
|
||||
Linux (arm64) 1 >= 2.6.32, glibc >= 2.12 Ubuntu 24.04
|
||||
macOS (x86_64) 1 >= 11 macOS 13
|
||||
macOS (arm64) 1 >= 11 macOS 15
|
||||
Windows 64-bit 1 >= Windows 10 Version 1809 Windows Server 2022
|
||||
FreeBSD 1 >= 10 FreeBSD 13
|
||||
FreeBSD 1 >= 10 FreeBSD 14
|
||||
OpenBSD 2 >= 7
|
||||
MinGW 2 MinGW-w64
|
||||
Windows 64-bit 3 < Windows 10 Version 1809
|
||||
@ -28,10 +29,10 @@ your Windows version, run the "winver" command and look for "Version xxxx"
|
||||
Support types ~
|
||||
|
||||
* Tier 1: Officially supported and tested with CI. Any contributed patch
|
||||
MUST NOT break such systems.
|
||||
MUST NOT break support for such platforms.
|
||||
|
||||
* Tier 2: Officially supported, but not necessarily tested with CI. These
|
||||
systems are maintained to the best of our ability, without being a top
|
||||
* Tier 2: Officially supported, but not necessarily tested with CI. Support
|
||||
for these platforms are maintained by best effort, without being a top
|
||||
priority.
|
||||
|
||||
* Tier 3: Not tested and no guarantees, and not all features may work.
|
||||
@ -47,7 +48,8 @@ Common
|
||||
|
||||
Some common notes when adding support for new platforms:
|
||||
|
||||
Cmake is the only supported build system. The platform must be buildable with cmake.
|
||||
CMake is the only supported build system. Nvim must be buildable on the
|
||||
platform with CMake.
|
||||
|
||||
All functionality related to the new platform must be implemented in its own
|
||||
file inside `src/nvim/os` unless it's already done in a common file, in which
|
||||
|
@ -152,8 +152,7 @@ add a few items or change the highlighting, follow these steps:
|
||||
1. Create your user directory from 'runtimepath', see above.
|
||||
|
||||
2. Create a directory in there called "after/syntax". For Unix: >
|
||||
mkdir ~/.config/nvim/after
|
||||
mkdir ~/.config/nvim/after/syntax
|
||||
mkdir -p ~/.config/nvim/after/syntax
|
||||
|
||||
3. Write a Vim script that contains the commands you want to use. For
|
||||
example, to change the colors for the C syntax: >
|
||||
@ -4986,7 +4985,6 @@ IncSearch 'incsearch' highlighting; also used for the text replaced with
|
||||
":s///c".
|
||||
*hl-Substitute*
|
||||
Substitute |:substitute| replacement text highlighting.
|
||||
|
||||
*hl-LineNr*
|
||||
LineNr Line number for ":number" and ":#" commands, and when 'number'
|
||||
or 'relativenumber' option is set.
|
||||
@ -5006,7 +5004,6 @@ CursorLineSign Like SignColumn when 'cursorline' is set for the cursor line.
|
||||
*hl-MatchParen*
|
||||
MatchParen Character under the cursor or just before it, if it
|
||||
is a paired bracket, and its match. |pi_paren.txt|
|
||||
|
||||
*hl-ModeMsg*
|
||||
ModeMsg 'showmode' message (e.g., "-- INSERT --").
|
||||
*hl-MsgArea*
|
||||
@ -5052,7 +5049,7 @@ PmenuThumb Popup menu: Thumb of the scrollbar.
|
||||
Question |hit-enter| prompt and yes/no questions.
|
||||
*hl-QuickFixLine*
|
||||
QuickFixLine Current |quickfix| item in the quickfix window. Combined with
|
||||
|hl-CursorLine| when the cursor is there.
|
||||
|hl-CursorLine| when the cursor is there.
|
||||
*hl-Search*
|
||||
Search Last search pattern highlighting (see 'hlsearch').
|
||||
Also used for similar items that need to stand out.
|
||||
|
@ -330,7 +330,7 @@ TREESITTER QUERY DIRECTIVES *treesitter-directives*
|
||||
Treesitter directives store metadata for a node or match and perform side
|
||||
effects. For example, the `set!` directive sets metadata on the match or node: >query
|
||||
|
||||
((identifier) @foo (#set! "type" "parameter"))
|
||||
((identifier) @foo (#set! type "parameter"))
|
||||
<
|
||||
The following directives are built in:
|
||||
|
||||
@ -345,9 +345,9 @@ The following directives are built in:
|
||||
{value}
|
||||
|
||||
Examples: >query
|
||||
((identifier) @foo (#set! @foo "kind" "parameter"))
|
||||
((node1) @left (node2) @right (#set! "type" "pair"))
|
||||
((codeblock) @markup.raw.block (#set! "priority" 90))
|
||||
((identifier) @foo (#set! @foo kind "parameter"))
|
||||
((node1) @left (node2) @right (#set! type "pair"))
|
||||
((codeblock) @markup.raw.block (#set! priority 90))
|
||||
<
|
||||
`offset!` *treesitter-directive-offset!*
|
||||
Takes the range of the captured node and applies an offset. This will
|
||||
@ -631,7 +631,7 @@ higher than treesitter. It is also possible to change the priority of an
|
||||
individual query pattern manually by setting its `"priority"` metadata
|
||||
attribute: >query
|
||||
|
||||
((super_important_node) @superimportant (#set! "priority" 105))
|
||||
((super_important_node) @superimportant (#set! priority 105))
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
|
@ -87,7 +87,7 @@ The ":tags" command shows the list of tags that you traversed through:
|
||||
1 1 write_line 8 write_block.c ~
|
||||
2 1 write_char 7 write_line.c ~
|
||||
> ~
|
||||
>
|
||||
<
|
||||
Now to go back. The CTRL-T command goes to the preceding tag. In the example
|
||||
above you get back to the "write_line" function, in the call to "write_char".
|
||||
This command takes a count argument that indicates how many tags to jump
|
||||
|
@ -209,7 +209,7 @@ gx Opens the current filepath or URL (decided by
|
||||
This implies that an insert command must be completed
|
||||
(to start Insert mode, see |:startinsert|). A ":"
|
||||
command must be completed as well. And you can't use
|
||||
"Q" or "gQ" to start Ex mode.
|
||||
"gQ" to start Ex mode.
|
||||
|
||||
The display is not updated while ":normal" is busy.
|
||||
|
||||
@ -579,6 +579,10 @@ Acting on multiple lines behaves as follows:
|
||||
transformed to empty comments (e.g. `/**/`). Comment markers are aligned to
|
||||
the least indented line.
|
||||
|
||||
Matching 'commentstring' does not account for whitespace in comment markers.
|
||||
Removing comment markers is first attempted exactly, with fallback to using
|
||||
markers trimmed from whitespace.
|
||||
|
||||
If the filetype of the buffer is associated with a language for which a
|
||||
|treesitter| parser is installed, then |vim.filetype.get_option()| is called
|
||||
to look up the value of 'commentstring' corresponding to the cursor position.
|
||||
|
@ -62,6 +62,7 @@ Defaults *nvim-defaults*
|
||||
- 'isfname' does not include ":" (on Windows). Drive letters are handled
|
||||
correctly without it. (Use |gF| for filepaths suffixed with ":line:col").
|
||||
- 'joinspaces' is disabled
|
||||
- 'jumpoptions' defaults to "clean"
|
||||
- 'langnoremap' is enabled
|
||||
- 'langremap' is disabled
|
||||
- 'laststatus' defaults to 2 (statusline is always shown)
|
||||
@ -326,6 +327,7 @@ string options work.
|
||||
- 'inccommand' shows interactive results for |:substitute|-like commands
|
||||
and |:command-preview| commands
|
||||
- 'jumpoptions' "view" tries to restore the |mark-view| when moving through
|
||||
"clean" removes unloaded buffer from the jumplist
|
||||
- the |jumplist|, |changelist|, |alternate-file| or using |mark-motions|.
|
||||
- 'laststatus' global statusline support
|
||||
- 'mousescroll' amount to scroll by when scrolling with a mouse
|
||||
|
@ -53,11 +53,17 @@ active yes yes 'a'
|
||||
hidden no yes 'h'
|
||||
inactive no no ' '
|
||||
|
||||
Note: All CTRL-W commands can also be executed with |:wincmd|, for those
|
||||
places where a Normal mode command can't be used or is inconvenient.
|
||||
*buffer-reuse*
|
||||
Each buffer has a unique number and the number will not change within a Vim
|
||||
session. The |bufnr()| and |bufname()| functions can be used to convert
|
||||
between a buffer name and the buffer number. There is one exception: if a new
|
||||
empty buffer is created and it is not modified, the buffer will be re-used
|
||||
when loading another file into that buffer. This also means the buffer number
|
||||
will not change.
|
||||
|
||||
The main Vim window can hold several split windows. There are also tab pages
|
||||
|tab-page|, each of which can hold multiple windows.
|
||||
|
||||
*window-ID* *winid* *windowid*
|
||||
Each window has a unique identifier called the window ID. This identifier
|
||||
will not change within a Vim session. The |win_getid()| and |win_id2tabwin()|
|
||||
@ -69,9 +75,6 @@ across tabs. For most functions that take a window ID or a window number, the
|
||||
window number only applies to the current tab, while the window ID can refer
|
||||
to a window in any tab.
|
||||
|
||||
Each buffer has a unique number and the number will not change within a Vim
|
||||
session. The |bufnr()| and |bufname()| functions can be used to convert
|
||||
between a buffer name and the buffer number.
|
||||
|
||||
==============================================================================
|
||||
2. Starting Vim *windows-starting*
|
||||
@ -468,6 +471,10 @@ These commands can also be executed with ":wincmd":
|
||||
:exe nr .. "wincmd w"
|
||||
< This goes to window "nr".
|
||||
|
||||
Note: All CTRL-W commands can also be executed with |:wincmd|, for those
|
||||
places where a Normal mode command can't be used or is inconvenient (e.g.
|
||||
in a browser-based terminal).
|
||||
|
||||
==============================================================================
|
||||
5. Moving windows around *window-moving*
|
||||
|
||||
|
@ -13,8 +13,8 @@ vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
|
||||
end
|
||||
local ft, on_detect = vim.filetype.match({
|
||||
-- The unexpanded file name is needed here. #27914
|
||||
-- Neither args.file nor args.match are guaranteed to be unexpanded.
|
||||
filename = vim.fn.bufname(args.buf),
|
||||
-- However, bufname() can't be used, as it doesn't work with :doautocmd. #31306
|
||||
filename = args.file,
|
||||
buf = args.buf,
|
||||
})
|
||||
if not ft then
|
||||
|
@ -10,7 +10,8 @@ if exists("b:did_ftplugin")
|
||||
endif
|
||||
|
||||
" Behaves mostly just like C
|
||||
runtime! ftplugin/c.{vim,lua} ftplugin/c_*.{vim,lua} ftplugin/c/*.{vim,lua}
|
||||
" XXX: "[.]" in the first pattern makes it a wildcard on Windows
|
||||
runtime! ftplugin/c[.]{vim,lua} ftplugin/c_*.{vim,lua} ftplugin/c/*.{vim,lua}
|
||||
|
||||
" C++ uses templates with <things>
|
||||
" Disabled, because it gives an error for typing an unmatched ">".
|
||||
|
3
runtime/ftplugin/dot.lua
Normal file
3
runtime/ftplugin/dot.lua
Normal file
@ -0,0 +1,3 @@
|
||||
vim.bo.commentstring = '// %s'
|
||||
|
||||
vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '') .. '\n setl commentstring<'
|
3
runtime/ftplugin/faust.lua
Normal file
3
runtime/ftplugin/faust.lua
Normal file
@ -0,0 +1,3 @@
|
||||
vim.bo.commentstring = '// %s'
|
||||
|
||||
vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '') .. '\n setl commentstring<'
|
1
runtime/ftplugin/glsl.lua
Normal file
1
runtime/ftplugin/glsl.lua
Normal file
@ -0,0 +1 @@
|
||||
vim.bo.commentstring = '// %s'
|
3
runtime/ftplugin/stata.lua
Normal file
3
runtime/ftplugin/stata.lua
Normal file
@ -0,0 +1,3 @@
|
||||
vim.bo.commentstring = '// %s'
|
||||
|
||||
vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '') .. '\n setl commentstring<'
|
3
runtime/ftplugin/supercollider.lua
Normal file
3
runtime/ftplugin/supercollider.lua
Normal file
@ -0,0 +1,3 @@
|
||||
vim.bo.commentstring = '// %s'
|
||||
|
||||
vim.b.undo_ftplugin = (vim.b.undo_ftplugin or '') .. '\n setl commentstring<'
|
3
runtime/ftplugin/swift.lua
Normal file
3
runtime/ftplugin/swift.lua
Normal file
@ -0,0 +1,3 @@
|
||||
vim.bo.commentstring = '// %s'
|
||||
|
||||
vim.b.undo_ftplugin = vim.b.undo_ftplugin .. ' | setl commentstring<'
|
@ -470,7 +470,13 @@ local function put_page(page)
|
||||
-- XXX: nroff justifies text by filling it with whitespace. That interacts
|
||||
-- badly with our use of $MANWIDTH=999. Hack around this by using a fixed
|
||||
-- size for those whitespace regions.
|
||||
vim.cmd([[silent! keeppatterns keepjumps %s/\s\{199,}/\=repeat(' ', 10)/g]])
|
||||
-- Use try/catch to avoid setting v:errmsg.
|
||||
vim.cmd([[
|
||||
try
|
||||
keeppatterns keepjumps %s/\s\{199,}/\=repeat(' ', 10)/g
|
||||
catch
|
||||
endtry
|
||||
]])
|
||||
vim.cmd('1') -- Move cursor to first line
|
||||
highlight_man_page()
|
||||
set_options()
|
||||
@ -708,7 +714,7 @@ function M.open_page(count, smods, args)
|
||||
end
|
||||
|
||||
sect, name = extract_sect_and_name_path(path)
|
||||
local buf = fn.bufnr()
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local save_tfu = vim.bo[buf].tagfunc
|
||||
vim.bo[buf].tagfunc = "v:lua.require'man'.goto_tag"
|
||||
|
||||
@ -724,7 +730,9 @@ function M.open_page(count, smods, args)
|
||||
end
|
||||
end)
|
||||
|
||||
vim.bo[buf].tagfunc = save_tfu
|
||||
if api.nvim_buf_is_valid(buf) then
|
||||
vim.bo[buf].tagfunc = save_tfu
|
||||
end
|
||||
|
||||
if not ok then
|
||||
error(ret)
|
||||
|
@ -50,11 +50,11 @@ local function check_config()
|
||||
|
||||
local init_lua = vim.fn.stdpath('config') .. '/init.lua'
|
||||
local init_vim = vim.fn.stdpath('config') .. '/init.vim'
|
||||
local vimrc = vim.env.MYVIMRC and vim.fn.expand(vim.env.MYVIMRC) or init_lua
|
||||
local vimrc = vim.env.MYVIMRC and vim.fs.normalize(vim.env.MYVIMRC) or init_lua
|
||||
|
||||
if vim.fn.filereadable(vimrc) == 0 and vim.fn.filereadable(init_vim) == 0 then
|
||||
ok = false
|
||||
local has_vim = vim.fn.filereadable(vim.fn.expand('~/.vimrc')) == 1
|
||||
local has_vim = vim.fn.filereadable(vim.fs.normalize('~/.vimrc')) == 1
|
||||
health.warn(
|
||||
('%s user config file: %s'):format(
|
||||
-1 == vim.fn.getfsize(vimrc) and 'Missing' or 'Unreadable',
|
||||
@ -114,7 +114,7 @@ local function check_config()
|
||||
)
|
||||
shadafile = (
|
||||
vim.o.shadafile == ''
|
||||
and (shadafile == '' and vim.fn.stdpath('state') .. '/shada/main.shada' or vim.fn.expand(
|
||||
and (shadafile == '' and vim.fn.stdpath('state') .. '/shada/main.shada' or vim.fs.normalize(
|
||||
shadafile
|
||||
))
|
||||
or (vim.o.shadafile == 'NONE' and '' or vim.o.shadafile)
|
||||
|
@ -1,5 +1,5 @@
|
||||
local health = vim.health
|
||||
local iswin = vim.loop.os_uname().sysname == 'Windows_NT'
|
||||
local iswin = vim.fn.has('win32') == 1
|
||||
|
||||
local M = {}
|
||||
|
||||
@ -7,7 +7,7 @@ local function is(path, ty)
|
||||
if not path then
|
||||
return false
|
||||
end
|
||||
local stat = vim.loop.fs_stat(path)
|
||||
local stat = vim.uv.fs_stat(path)
|
||||
if not stat then
|
||||
return false
|
||||
end
|
||||
@ -36,7 +36,17 @@ local function check_for_pyenv()
|
||||
local pyenv_root = vim.fn.resolve(os.getenv('PYENV_ROOT') or '')
|
||||
|
||||
if pyenv_root == '' then
|
||||
pyenv_root = vim.fn.system({ pyenv_path, 'root' })
|
||||
local p = vim.system({ pyenv_path, 'root' }):wait()
|
||||
if p.code ~= 0 then
|
||||
local message = string.format(
|
||||
'pyenv: Failed to infer the root of pyenv by running `%s root` : %s. Ignoring pyenv for all following checks.',
|
||||
pyenv_path,
|
||||
p.stderr
|
||||
)
|
||||
health.warn(message)
|
||||
return { '', '' }
|
||||
end
|
||||
pyenv_root = vim.trim(p.stdout)
|
||||
health.info('pyenv: $PYENV_ROOT is not set. Infer from `pyenv root`.')
|
||||
end
|
||||
|
||||
@ -77,12 +87,14 @@ local function download(url)
|
||||
return out
|
||||
end
|
||||
elseif vim.fn.executable('python') == 1 then
|
||||
local script = "try:\n\
|
||||
from urllib.request import urlopen\n\
|
||||
except ImportError:\n\
|
||||
from urllib2 import urlopen\n\
|
||||
response = urlopen('" .. url .. "')\n\
|
||||
print(response.read().decode('utf8'))\n"
|
||||
local script = ([[
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from urllib2 import urlopen
|
||||
response = urlopen('%s')
|
||||
print(response.read().decode('utf8'))
|
||||
]]):format(url)
|
||||
local out, rc = health.system({ 'python', '-c', script })
|
||||
if out == '' and rc ~= 0 then
|
||||
return 'python urllib.request error: ' .. rc
|
||||
@ -425,7 +437,7 @@ function M.check()
|
||||
local venv_bins = vim.fn.glob(string.format('%s/%s/python*', virtual_env, bin_dir), true, true)
|
||||
venv_bins = vim.tbl_filter(function(v)
|
||||
-- XXX: Remove irrelevant executables found in bin/.
|
||||
return not v:match('python%-config')
|
||||
return not v:match('python.*%-config')
|
||||
end, venv_bins)
|
||||
if vim.tbl_count(venv_bins) > 0 then
|
||||
for _, venv_bin in pairs(venv_bins) do
|
||||
|
@ -19,8 +19,7 @@ function M.check()
|
||||
end
|
||||
health.info('Ruby: ' .. health.system({ 'ruby', '-v' }))
|
||||
|
||||
local ruby_detect_table = vim.provider.ruby.detect()
|
||||
local host = ruby_detect_table[1]
|
||||
local host, _ = vim.provider.ruby.detect()
|
||||
if (not host) or host:find('^%s*$') then
|
||||
health.warn('`neovim-ruby-host` not found.', {
|
||||
'Run `gem install neovim` to ensure the neovim RubyGem is installed.',
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- @brief
|
||||
---<pre>help
|
||||
---:TOhtml {file} *:TOhtml*
|
||||
---:[range]TOhtml {file} *:TOhtml*
|
||||
---Converts the buffer shown in the current window to HTML, opens the generated
|
||||
---HTML in a new split window, and saves its contents to {file}. If {file} is not
|
||||
---given, a temporary file (created by |tempname()|) is used.
|
||||
@ -40,7 +40,8 @@
|
||||
--- @field winid integer
|
||||
--- @field bufnr integer
|
||||
--- @field width integer
|
||||
--- @field buflen integer
|
||||
--- @field start integer
|
||||
--- @field end_ integer
|
||||
|
||||
--- @class (private) vim.tohtml.styletable
|
||||
--- @field [integer] vim.tohtml.line (integer: (1-index, exclusive))
|
||||
@ -57,6 +58,26 @@
|
||||
--- @field [3] any[][] virt_text
|
||||
--- @field [4] any[][] overlay_text
|
||||
|
||||
--- @type string[]
|
||||
local notifications = {}
|
||||
|
||||
---@param msg string
|
||||
local function notify(msg)
|
||||
if #notifications == 0 then
|
||||
vim.schedule(function()
|
||||
if #notifications > 1 then
|
||||
vim.notify(
|
||||
('TOhtml: %s (+ %d more warnings)'):format(notifications[1], tostring(#notifications - 1))
|
||||
)
|
||||
elseif #notifications == 1 then
|
||||
vim.notify('TOhtml: ' .. notifications[1])
|
||||
end
|
||||
notifications = {}
|
||||
end)
|
||||
end
|
||||
table.insert(notifications, msg)
|
||||
end
|
||||
|
||||
local HIDE_ID = -1
|
||||
-- stylua: ignore start
|
||||
local cterm_8_to_hex={
|
||||
@ -168,6 +189,8 @@ local background_color_cache = nil
|
||||
--- @type string?
|
||||
local foreground_color_cache = nil
|
||||
|
||||
local len = vim.api.nvim_strwidth
|
||||
|
||||
--- @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
|
||||
--- @param color "background"|"foreground"|integer
|
||||
--- @return string?
|
||||
@ -215,7 +238,7 @@ local function cterm_to_hex(colorstr)
|
||||
if hex then
|
||||
cterm_color_cache[color] = hex
|
||||
else
|
||||
vim.notify_once("Info(TOhtml): Couldn't get terminal colors, using fallback")
|
||||
notify("Couldn't get terminal colors, using fallback")
|
||||
local t_Co = tonumber(vim.api.nvim_eval('&t_Co'))
|
||||
if t_Co <= 8 then
|
||||
cterm_color_cache = cterm_8_to_hex
|
||||
@ -241,7 +264,7 @@ local function get_background_color()
|
||||
end
|
||||
local hex = try_query_terminal_color('background')
|
||||
if not hex or not hex:match('#%x%x%x%x%x%x') then
|
||||
vim.notify_once("Info(TOhtml): Couldn't get terminal background colors, using fallback")
|
||||
notify("Couldn't get terminal background colors, using fallback")
|
||||
hex = vim.o.background == 'light' and '#ffffff' or '#000000'
|
||||
end
|
||||
background_color_cache = hex
|
||||
@ -259,7 +282,7 @@ local function get_foreground_color()
|
||||
end
|
||||
local hex = try_query_terminal_color('foreground')
|
||||
if not hex or not hex:match('#%x%x%x%x%x%x') then
|
||||
vim.notify_once("Info(TOhtml): Couldn't get terminal foreground colors, using fallback")
|
||||
notify("Couldn't get terminal foreground colors, using fallback")
|
||||
hex = vim.o.background == 'light' and '#000000' or '#ffffff'
|
||||
end
|
||||
foreground_color_cache = hex
|
||||
@ -292,9 +315,12 @@ local function style_line_insert_virt_text(style_line, col, val)
|
||||
end
|
||||
|
||||
--- @param state vim.tohtml.state
|
||||
--- @param hl string|integer|nil
|
||||
--- @param hl string|integer|string[]|integer[]?
|
||||
--- @return nil|integer
|
||||
local function register_hl(state, hl)
|
||||
if type(hl) == 'table' then
|
||||
hl = hl[#hl]
|
||||
end
|
||||
if type(hl) == 'nil' then
|
||||
return
|
||||
elseif type(hl) == 'string' then
|
||||
@ -370,7 +396,7 @@ end
|
||||
|
||||
--- @param state vim.tohtml.state
|
||||
local function styletable_syntax(state)
|
||||
for row = 1, state.buflen do
|
||||
for row = state.start, state.end_ do
|
||||
local prev_id = 0
|
||||
local prev_col = nil
|
||||
for col = 1, #vim.fn.getline(row) + 1 do
|
||||
@ -390,7 +416,7 @@ end
|
||||
--- @param state vim.tohtml.state
|
||||
local function styletable_diff(state)
|
||||
local styletable = state.style
|
||||
for row = 1, state.buflen do
|
||||
for row = state.start, state.end_ do
|
||||
local style_line = styletable[row]
|
||||
local filler = vim.fn.diff_filler(row)
|
||||
if filler ~= 0 then
|
||||
@ -400,7 +426,7 @@ local function styletable_diff(state)
|
||||
{ { fill:rep(state.width), register_hl(state, 'DiffDelete') } }
|
||||
)
|
||||
end
|
||||
if row == state.buflen + 1 then
|
||||
if row == state.end_ + 1 then
|
||||
break
|
||||
end
|
||||
local prev_id = 0
|
||||
@ -442,7 +468,9 @@ local function styletable_treesitter(state)
|
||||
if not query then
|
||||
return
|
||||
end
|
||||
for capture, node, metadata in query:iter_captures(root, buf_highlighter.bufnr, 0, state.buflen) do
|
||||
for capture, node, metadata in
|
||||
query:iter_captures(root, buf_highlighter.bufnr, state.start - 1, state.end_)
|
||||
do
|
||||
local srow, scol, erow, ecol = node:range()
|
||||
--- @diagnostic disable-next-line: invisible
|
||||
local c = q._query.captures[capture]
|
||||
@ -467,7 +495,7 @@ local function _styletable_extmarks_highlight(state, extmark, namespaces)
|
||||
---TODO(altermo) LSP semantic tokens (and some other extmarks) are only
|
||||
---generated in visible lines, and not in the whole buffer.
|
||||
if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_semantic_tokens') then
|
||||
vim.notify_once('Info(TOhtml): lsp semantic tokens are not supported, HTML may be incorrect')
|
||||
notify('lsp semantic tokens are not supported, HTML may be incorrect')
|
||||
return
|
||||
end
|
||||
local srow, scol, erow, ecol =
|
||||
@ -481,17 +509,27 @@ end
|
||||
|
||||
--- @param state vim.tohtml.state
|
||||
--- @param extmark {[1]:integer,[2]:integer,[3]:integer,[4]:vim.api.keyset.set_extmark|any}
|
||||
local function _styletable_extmarks_virt_text(state, extmark)
|
||||
--- @param namespaces table<integer,string>
|
||||
local function _styletable_extmarks_virt_text(state, extmark, namespaces)
|
||||
if not extmark[4].virt_text then
|
||||
return
|
||||
end
|
||||
---TODO(altermo) LSP semantic tokens (and some other extmarks) are only
|
||||
---generated in visible lines, and not in the whole buffer.
|
||||
if (namespaces[extmark[4].ns_id] or ''):find('vim_lsp_inlayhint') then
|
||||
notify('lsp inlay hints are not supported, HTML may be incorrect')
|
||||
return
|
||||
end
|
||||
local styletable = state.style
|
||||
--- @type integer,integer
|
||||
local row, col = extmark[2], extmark[3]
|
||||
if
|
||||
extmark[4].virt_text_pos == 'inline'
|
||||
or extmark[4].virt_text_pos == 'eol'
|
||||
or extmark[4].virt_text_pos == 'overlay'
|
||||
row < vim.api.nvim_buf_line_count(state.bufnr)
|
||||
and (
|
||||
extmark[4].virt_text_pos == 'inline'
|
||||
or extmark[4].virt_text_pos == 'eol'
|
||||
or extmark[4].virt_text_pos == 'overlay'
|
||||
)
|
||||
then
|
||||
if extmark[4].virt_text_pos == 'eol' then
|
||||
style_line_insert_virt_text(styletable[row + 1], #vim.fn.getline(row + 1) + 1, { ' ' })
|
||||
@ -510,7 +548,7 @@ local function _styletable_extmarks_virt_text(state, extmark)
|
||||
else
|
||||
style_line_insert_virt_text(styletable[row + 1], col + 1, { i[1], hlid })
|
||||
end
|
||||
virt_text_len = virt_text_len + #i[1]
|
||||
virt_text_len = virt_text_len + len(i[1])
|
||||
end
|
||||
if extmark[4].virt_text_pos == 'overlay' then
|
||||
styletable_insert_range(state, row + 1, col + 1, row + 1, col + virt_text_len + 1, HIDE_ID)
|
||||
@ -521,11 +559,9 @@ local function _styletable_extmarks_virt_text(state, extmark)
|
||||
hl_mode = 'blend',
|
||||
hl_group = 'combine',
|
||||
}
|
||||
for opt, val in ipairs(not_supported) do
|
||||
for opt, val in pairs(not_supported) do
|
||||
if extmark[4][opt] == val then
|
||||
vim.notify_once(
|
||||
('Info(TOhtml): extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val)
|
||||
)
|
||||
notify(('extmark.%s="%s" is not supported, HTML may be incorrect'):format(opt, val))
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -586,7 +622,7 @@ local function styletable_extmarks(state)
|
||||
_styletable_extmarks_conceal(state, v)
|
||||
end
|
||||
for _, v in ipairs(extmarks) do
|
||||
_styletable_extmarks_virt_text(state, v)
|
||||
_styletable_extmarks_virt_text(state, v, namespaces)
|
||||
end
|
||||
for _, v in ipairs(extmarks) do
|
||||
_styletable_extmarks_virt_lines(state, v)
|
||||
@ -597,7 +633,7 @@ end
|
||||
local function styletable_folds(state)
|
||||
local styletable = state.style
|
||||
local has_folded = false
|
||||
for row = 1, state.buflen do
|
||||
for row = state.start, state.end_ do
|
||||
if vim.fn.foldclosed(row) > 0 then
|
||||
has_folded = true
|
||||
styletable[row].hide = true
|
||||
@ -611,9 +647,7 @@ local function styletable_folds(state)
|
||||
end
|
||||
end
|
||||
if has_folded and type(({ pcall(vim.api.nvim_eval, vim.o.foldtext) })[2]) == 'table' then
|
||||
vim.notify_once(
|
||||
'Info(TOhtml): foldtext returning a table is half supported, HTML may be incorrect'
|
||||
)
|
||||
notify('foldtext returning a table with highlights is not supported, HTML may be incorrect')
|
||||
end
|
||||
end
|
||||
|
||||
@ -621,7 +655,7 @@ end
|
||||
local function styletable_conceal(state)
|
||||
local bufnr = state.bufnr
|
||||
vim.api.nvim_buf_call(bufnr, function()
|
||||
for row = 1, state.buflen do
|
||||
for row = state.start, state.end_ do
|
||||
--- @type table<integer,{[1]:integer,[2]:integer,[3]:string}>
|
||||
local conceals = {}
|
||||
local line_len_exclusive = #vim.fn.getline(row) + 1
|
||||
@ -739,7 +773,7 @@ local function styletable_statuscolumn(state)
|
||||
local max = tonumber(foldcolumn:match('^%w-:(%d)')) or 1
|
||||
local maxfold = 0
|
||||
vim.api.nvim_buf_call(state.bufnr, function()
|
||||
for row = 1, vim.api.nvim_buf_line_count(state.bufnr) do
|
||||
for row = state.start, state.end_ do
|
||||
local foldlevel = vim.fn.foldlevel(row)
|
||||
if foldlevel > maxfold then
|
||||
maxfold = foldlevel
|
||||
@ -754,12 +788,12 @@ local function styletable_statuscolumn(state)
|
||||
|
||||
--- @type table<integer,any>
|
||||
local statuses = {}
|
||||
for row = 1, state.buflen do
|
||||
for row = state.start, state.end_ do
|
||||
local status = vim.api.nvim_eval_statusline(
|
||||
statuscolumn,
|
||||
{ winid = state.winid, use_statuscol_lnum = row, highlights = true }
|
||||
)
|
||||
local width = vim.api.nvim_strwidth(status.str)
|
||||
local width = len(status.str)
|
||||
if width > minwidth then
|
||||
minwidth = width
|
||||
end
|
||||
@ -774,7 +808,7 @@ local function styletable_statuscolumn(state)
|
||||
for k, v in ipairs(hls) do
|
||||
local text = str:sub(v.start + 1, hls[k + 1] and hls[k + 1].start or nil)
|
||||
if k == #hls then
|
||||
text = text .. (' '):rep(minwidth - vim.api.nvim_strwidth(str))
|
||||
text = text .. (' '):rep(minwidth - len(str))
|
||||
end
|
||||
if text ~= '' then
|
||||
local hlid = register_hl(state, v.group)
|
||||
@ -794,7 +828,6 @@ local function styletable_listchars(state)
|
||||
local function utf8_sub(str, i, j)
|
||||
return vim.fn.strcharpart(str, i - 1, j and j - i + 1 or nil)
|
||||
end
|
||||
local len = vim.api.nvim_strwidth
|
||||
--- @type table<string,string>
|
||||
local listchars = vim.opt_local.listchars:get()
|
||||
local ids = setmetatable({}, {
|
||||
@ -805,7 +838,7 @@ local function styletable_listchars(state)
|
||||
})
|
||||
|
||||
if listchars.eol then
|
||||
for row = 1, state.buflen do
|
||||
for row = state.start, state.end_ do
|
||||
local style_line = state.style[row]
|
||||
style_line_insert_overlay_char(
|
||||
style_line,
|
||||
@ -1099,16 +1132,22 @@ end
|
||||
local function extend_pre(out, state)
|
||||
local styletable = state.style
|
||||
table.insert(out, '<pre>')
|
||||
local out_start = #out
|
||||
local hide_count = 0
|
||||
--- @type integer[]
|
||||
local stack = {}
|
||||
|
||||
local before = ''
|
||||
local after = ''
|
||||
local function loop(row)
|
||||
local inside = row <= state.end_ and row >= state.start
|
||||
local style_line = styletable[row]
|
||||
if style_line.hide and (styletable[row - 1] or {}).hide then
|
||||
return
|
||||
end
|
||||
_extend_virt_lines(out, state, row)
|
||||
if inside then
|
||||
_extend_virt_lines(out, state, row)
|
||||
end
|
||||
--Possible improvement (altermo):
|
||||
--Instead of looping over all the buffer characters per line,
|
||||
--why not loop over all the style_line cells,
|
||||
@ -1118,8 +1157,16 @@ local function extend_pre(out, state)
|
||||
end
|
||||
local line = vim.api.nvim_buf_get_lines(state.bufnr, row - 1, row, false)[1] or ''
|
||||
local s = ''
|
||||
s = s .. _pre_text_to_html(state, row)
|
||||
for col = 1, #line + 1 do
|
||||
if inside then
|
||||
s = s .. _pre_text_to_html(state, row)
|
||||
end
|
||||
local true_line_len = #line + 1
|
||||
for k in pairs(style_line) do
|
||||
if type(k) == 'number' and k > true_line_len then
|
||||
true_line_len = k
|
||||
end
|
||||
end
|
||||
for col = 1, true_line_len do
|
||||
local cell = style_line[col]
|
||||
--- @type table?
|
||||
local char
|
||||
@ -1159,18 +1206,18 @@ local function extend_pre(out, state)
|
||||
end
|
||||
end
|
||||
|
||||
if cell[3] then
|
||||
if cell[3] and inside then
|
||||
s = s .. _virt_text_to_html(state, cell)
|
||||
end
|
||||
|
||||
char = cell[4][#cell[4]]
|
||||
end
|
||||
|
||||
if col == #line + 1 and not char then
|
||||
if col == true_line_len and not char then
|
||||
break
|
||||
end
|
||||
|
||||
if hide_count == 0 then
|
||||
if hide_count == 0 and inside then
|
||||
s = s
|
||||
.. _char_to_html(
|
||||
state,
|
||||
@ -1179,12 +1226,20 @@ local function extend_pre(out, state)
|
||||
)
|
||||
end
|
||||
end
|
||||
table.insert(out, s)
|
||||
if row > state.end_ + 1 then
|
||||
after = after .. s
|
||||
elseif row < state.start then
|
||||
before = s .. before
|
||||
else
|
||||
table.insert(out, s)
|
||||
end
|
||||
end
|
||||
|
||||
for row = 1, state.buflen + 1 do
|
||||
for row = 1, vim.api.nvim_buf_line_count(state.bufnr) + 1 do
|
||||
loop(row)
|
||||
end
|
||||
out[out_start] = out[out_start] .. before
|
||||
out[#out] = out[#out] .. after
|
||||
assert(#stack == 0, 'an open HTML tag was never closed')
|
||||
table.insert(out, '</pre>')
|
||||
end
|
||||
@ -1216,6 +1271,7 @@ local function global_state_to_state(winid, global_state)
|
||||
if not width or width < 1 then
|
||||
width = vim.api.nvim_win_get_width(winid)
|
||||
end
|
||||
local range = opt.range or { 1, vim.api.nvim_buf_line_count(bufnr) }
|
||||
local state = setmetatable({
|
||||
winid = winid == 0 and vim.api.nvim_get_current_win() or winid,
|
||||
opt = vim.wo[winid],
|
||||
@ -1223,7 +1279,8 @@ local function global_state_to_state(winid, global_state)
|
||||
bufnr = bufnr,
|
||||
tabstop = (' '):rep(vim.bo[bufnr].tabstop),
|
||||
width = width,
|
||||
buflen = vim.api.nvim_buf_line_count(bufnr),
|
||||
start = range[1],
|
||||
end_ = range[2],
|
||||
}, { __index = global_state })
|
||||
return state --[[@as vim.tohtml.state]]
|
||||
end
|
||||
@ -1282,35 +1339,22 @@ local function state_generate_style(state)
|
||||
end)
|
||||
end
|
||||
|
||||
--- @param winid integer[]|integer
|
||||
--- @param winid integer
|
||||
--- @param opt? vim.tohtml.opt
|
||||
--- @return string[]
|
||||
local function win_to_html(winid, opt)
|
||||
if type(winid) == 'number' then
|
||||
winid = { winid }
|
||||
end
|
||||
--- @cast winid integer[]
|
||||
assert(#winid > 0, 'no window specified')
|
||||
opt = opt or {}
|
||||
local title = table.concat(
|
||||
vim.tbl_map(vim.api.nvim_buf_get_name, vim.tbl_map(vim.api.nvim_win_get_buf, winid)),
|
||||
','
|
||||
)
|
||||
local title = vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(winid))
|
||||
|
||||
local global_state = opt_to_global_state(opt, title)
|
||||
--- @type vim.tohtml.state[]
|
||||
local states = {}
|
||||
for _, i in ipairs(winid) do
|
||||
local state = global_state_to_state(i, global_state)
|
||||
state_generate_style(state)
|
||||
table.insert(states, state)
|
||||
end
|
||||
local state = global_state_to_state(winid, global_state)
|
||||
state_generate_style(state)
|
||||
|
||||
local html = {}
|
||||
extend_html(html, function()
|
||||
extend_head(html, global_state)
|
||||
extend_body(html, function()
|
||||
for _, state in ipairs(states) do
|
||||
extend_pre(html, state)
|
||||
end
|
||||
extend_pre(html, state)
|
||||
end)
|
||||
end)
|
||||
return html
|
||||
@ -1337,6 +1381,10 @@ local M = {}
|
||||
--- infinitely.
|
||||
--- (default: 'textwidth' if non-zero or window width otherwise)
|
||||
--- @field width? integer
|
||||
---
|
||||
--- Range of rows to use.
|
||||
--- (default: entire buffer)
|
||||
--- @field range? integer[]
|
||||
|
||||
--- Converts the buffer shown in the window {winid} to HTML and returns the output as a list of string.
|
||||
--- @param winid? integer Window to convert (defaults to current window)
|
||||
|
@ -77,14 +77,11 @@ local function make_comment_check(parts)
|
||||
local l_esc, r_esc = vim.pesc(parts.left), vim.pesc(parts.right)
|
||||
|
||||
-- Commented line has the following structure:
|
||||
-- <possible whitespace> <left> <anything> <right> <possible whitespace>
|
||||
local nonblank_regex = '^%s-' .. l_esc .. '.*' .. r_esc .. '%s-$'
|
||||
|
||||
-- Commented blank line can have any amount of whitespace around parts
|
||||
local blank_regex = '^%s-' .. vim.trim(l_esc) .. '%s*' .. vim.trim(r_esc) .. '%s-$'
|
||||
-- <whitespace> <trimmed left> <anything> <trimmed right> <whitespace>
|
||||
local regex = '^%s-' .. vim.trim(l_esc) .. '.*' .. vim.trim(r_esc) .. '%s-$'
|
||||
|
||||
return function(line)
|
||||
return line:find(nonblank_regex) ~= nil or line:find(blank_regex) ~= nil
|
||||
return line:find(regex) ~= nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -153,14 +150,14 @@ end
|
||||
---@return fun(line: string): string
|
||||
local function make_uncomment_function(parts)
|
||||
local l_esc, r_esc = vim.pesc(parts.left), vim.pesc(parts.right)
|
||||
local nonblank_regex = '^(%s*)' .. l_esc .. '(.*)' .. r_esc .. '(%s-)$'
|
||||
local blank_regex = '^(%s*)' .. vim.trim(l_esc) .. '(%s*)' .. vim.trim(r_esc) .. '(%s-)$'
|
||||
local regex = '^(%s*)' .. l_esc .. '(.*)' .. r_esc .. '(%s-)$'
|
||||
local regex_trimmed = '^(%s*)' .. vim.trim(l_esc) .. '(.*)' .. vim.trim(r_esc) .. '(%s-)$'
|
||||
|
||||
return function(line)
|
||||
-- Try both non-blank and blank regexes
|
||||
local indent, new_line, trail = line:match(nonblank_regex)
|
||||
-- Try regex with exact comment parts first, fall back to trimmed parts
|
||||
local indent, new_line, trail = line:match(regex)
|
||||
if new_line == nil then
|
||||
indent, new_line, trail = line:match(blank_regex)
|
||||
indent, new_line, trail = line:match(regex_trimmed)
|
||||
end
|
||||
|
||||
-- Return original if line is not commented
|
||||
|
@ -49,10 +49,10 @@ do
|
||||
|
||||
vim.keymap.set('x', '*', function()
|
||||
return _visual_search('/')
|
||||
end, { desc = ':help v_star-default', expr = true, silent = true })
|
||||
end, { desc = ':help v_star-default', expr = true, replace_keycodes = false })
|
||||
vim.keymap.set('x', '#', function()
|
||||
return _visual_search('?')
|
||||
end, { desc = ':help v_#-default', expr = true, silent = true })
|
||||
end, { desc = ':help v_#-default', expr = true, replace_keycodes = false })
|
||||
end
|
||||
|
||||
--- Map Y to y$. This mimics the behavior of D and C. See |Y-default|
|
||||
@ -85,13 +85,13 @@ do
|
||||
vim.keymap.set(
|
||||
'x',
|
||||
'Q',
|
||||
"mode() == 'V' ? ':normal! @<C-R>=reg_recorded()<CR><CR>' : 'Q'",
|
||||
"mode() ==# 'V' ? ':normal! @<C-R>=reg_recorded()<CR><CR>' : 'Q'",
|
||||
{ silent = true, expr = true, desc = ':help v_Q-default' }
|
||||
)
|
||||
vim.keymap.set(
|
||||
'x',
|
||||
'@',
|
||||
"mode() == 'V' ? ':normal! @'.getcharstr().'<CR>' : '@'",
|
||||
"mode() ==# 'V' ? ':normal! @'.getcharstr().'<CR>' : '@'",
|
||||
{ silent = true, expr = true, desc = ':help v_@-default' }
|
||||
)
|
||||
|
||||
@ -266,7 +266,10 @@ do
|
||||
return
|
||||
end
|
||||
vim.v.swapchoice = 'e' -- Choose "(E)dit".
|
||||
vim.notify(('W325: Ignoring swapfile from Nvim process %d'):format(info.pid))
|
||||
vim.notify(
|
||||
('W325: Ignoring swapfile from Nvim process %d'):format(info.pid),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end,
|
||||
})
|
||||
|
||||
@ -431,10 +434,14 @@ do
|
||||
--- response indicates that it does support truecolor enable 'termguicolors',
|
||||
--- but only if the user has not already disabled it.
|
||||
do
|
||||
if tty.rgb then
|
||||
-- The TUI was able to determine truecolor support
|
||||
local colorterm = os.getenv('COLORTERM')
|
||||
if tty.rgb or colorterm == 'truecolor' or colorterm == '24bit' then
|
||||
-- The TUI was able to determine truecolor support or $COLORTERM explicitly indicates
|
||||
-- truecolor support
|
||||
setoption('termguicolors', true)
|
||||
else
|
||||
elseif colorterm == nil or colorterm == '' then
|
||||
-- Neither the TUI nor $COLORTERM indicate that truecolor is supported, so query the
|
||||
-- terminal
|
||||
local caps = {} ---@type table<string, boolean>
|
||||
require('vim.termcap').query({ 'Tc', 'RGB', 'setrgbf', 'setrgbb' }, function(cap, found)
|
||||
if not found then
|
||||
|
@ -656,15 +656,18 @@ local on_key_cbs = {} --- @type table<integer,function>
|
||||
---@note {fn} will be removed on error.
|
||||
---@note {fn} will not be cleared by |nvim_buf_clear_namespace()|
|
||||
---
|
||||
---@param fn fun(key: string, typed: string)?
|
||||
--- Function invoked on every key press. |i_CTRL-V|
|
||||
--- {key} is the key after mappings have been applied, and
|
||||
--- {typed} is the key(s) before mappings are applied, which
|
||||
--- may be empty if {key} is produced by non-typed keys.
|
||||
--- When {fn} is nil and {ns_id} is specified, the callback
|
||||
--- associated with namespace {ns_id} is removed.
|
||||
---@param fn fun(key: string, typed: string)? Function invoked for every input key,
|
||||
--- after mappings have been applied but before further processing. Arguments
|
||||
--- {key} and {typed} are raw keycodes, where {key} is the key after mappings
|
||||
--- are applied, and {typed} is the key(s) before mappings are applied.
|
||||
--- {typed} may be empty if {key} is produced by non-typed key(s) or by the
|
||||
--- same typed key(s) that produced a previous {key}.
|
||||
--- When {fn} is `nil` and {ns_id} is specified, the callback associated with
|
||||
--- namespace {ns_id} is removed.
|
||||
---@param ns_id integer? Namespace ID. If nil or 0, generates and returns a
|
||||
--- new |nvim_create_namespace()| id.
|
||||
--- new |nvim_create_namespace()| id.
|
||||
---
|
||||
---@see |keytrans()|
|
||||
---
|
||||
---@return integer Namespace id associated with {fn}. Or count of all callbacks
|
||||
---if on_key() is called without arguments.
|
||||
|
@ -169,7 +169,7 @@ function vim.show_pos(bufnr, row, col, filter)
|
||||
if data.hl_group ~= data.hl_group_link then
|
||||
append('links to ', 'MoreMsg')
|
||||
append(data.hl_group_link, data.hl_group_link)
|
||||
append(' ')
|
||||
append(' ')
|
||||
end
|
||||
if comment then
|
||||
append(comment, 'Comment')
|
||||
@ -182,7 +182,14 @@ function vim.show_pos(bufnr, row, col, filter)
|
||||
append('Treesitter', 'Title')
|
||||
nl()
|
||||
for _, capture in ipairs(items.treesitter) do
|
||||
item(capture, capture.lang)
|
||||
item(
|
||||
capture,
|
||||
string.format(
|
||||
'priority: %d language: %s',
|
||||
capture.metadata.priority or vim.highlight.priorities.treesitter,
|
||||
capture.lang
|
||||
)
|
||||
)
|
||||
end
|
||||
nl()
|
||||
end
|
||||
|
12
runtime/lua/vim/_meta/api.lua
generated
12
runtime/lua/vim/_meta/api.lua
generated
@ -956,9 +956,9 @@ function vim.api.nvim_create_augroup(name, opts) end
|
||||
--- • event: (string) name of the triggered event
|
||||
--- `autocmd-events`
|
||||
--- • group: (number|nil) autocommand group id, if any
|
||||
--- • match: (string) expanded value of <amatch>
|
||||
--- • buf: (number) expanded value of <abuf>
|
||||
--- • file: (string) expanded value of <afile>
|
||||
--- • file: (string) <afile> (not expanded to a full path)
|
||||
--- • match: (string) <amatch> (expanded to a full path)
|
||||
--- • buf: (number) <abuf>
|
||||
--- • data: (any) arbitrary data passed from
|
||||
--- `nvim_exec_autocmds()` *event-data*
|
||||
--- • command (string) optional: Vim command to execute on event.
|
||||
@ -1921,7 +1921,7 @@ function vim.api.nvim_set_current_win(window) end
|
||||
--- Note: this function should not be called often. Rather, the callbacks
|
||||
--- themselves can be used to throttle unneeded callbacks. the `on_start`
|
||||
--- callback can return `false` to disable the provider until the next redraw.
|
||||
--- Similarly, return `false` in `on_win` will skip the `on_lines` calls for
|
||||
--- Similarly, return `false` in `on_win` will skip the `on_line` calls for
|
||||
--- that window (but any extmarks set in `on_win` will still be used). A
|
||||
--- plugin managing multiple sources of decoration should ideally only set one
|
||||
--- provider, and merge the sources internally. You can use multiple `ns_id`
|
||||
@ -1930,10 +1930,10 @@ function vim.api.nvim_set_current_win(window) end
|
||||
--- Note: doing anything other than setting extmarks is considered
|
||||
--- experimental. Doing things like changing options are not explicitly
|
||||
--- forbidden, but is likely to have unexpected consequences (such as 100% CPU
|
||||
--- consumption). doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is
|
||||
--- consumption). Doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is
|
||||
--- quite dubious for the moment.
|
||||
---
|
||||
--- Note: It is not allowed to remove or update extmarks in 'on_line'
|
||||
--- Note: It is not allowed to remove or update extmarks in `on_line`
|
||||
--- callbacks.
|
||||
---
|
||||
--- @param ns_id integer Namespace id from `nvim_create_namespace()`
|
||||
|
@ -11,19 +11,19 @@
|
||||
--- - `count_a` (`integer`): Hunk size in {a}.
|
||||
--- - `start_b` (`integer`): Start line of hunk in {b}.
|
||||
--- - `count_b` (`integer`): Hunk size in {b}.
|
||||
--- @field on_hunk fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer
|
||||
--- @field on_hunk? fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer
|
||||
---
|
||||
--- Form of the returned diff:
|
||||
--- - `unified`: String in unified format.
|
||||
--- - `indices`: Array of hunk locations.
|
||||
--- Note: This option is ignored if `on_hunk` is used.
|
||||
--- (default: `'unified'`)
|
||||
--- @field result_type 'unified'|'indices'
|
||||
--- @field result_type? 'unified'|'indices'
|
||||
---
|
||||
--- Run linematch on the resulting hunks from xdiff. When integer, only hunks
|
||||
--- upto this size in lines are run through linematch.
|
||||
--- Requires `result_type = indices`, ignored otherwise.
|
||||
--- @field linematch boolean|integer
|
||||
--- @field linematch? boolean|integer
|
||||
---
|
||||
--- Diff algorithm to use. Values:
|
||||
--- - `myers`: the default algorithm
|
||||
@ -31,15 +31,15 @@
|
||||
--- - `patience`: patience diff algorithm
|
||||
--- - `histogram`: histogram diff algorithm
|
||||
--- (default: `'myers'`)
|
||||
--- @field algorithm 'myers'|'minimal'|'patience'|'histogram'
|
||||
--- @field ctxlen integer Context length
|
||||
--- @field interhunkctxlen integer Inter hunk context length
|
||||
--- @field ignore_whitespace boolean Ignore whitespace
|
||||
--- @field ignore_whitespace_change boolean Ignore whitespace change
|
||||
--- @field ignore_whitespace_change_at_eol boolean Ignore whitespace change at end-of-line.
|
||||
--- @field ignore_cr_at_eol boolean Ignore carriage return at end-of-line
|
||||
--- @field ignore_blank_lines boolean Ignore blank lines
|
||||
--- @field indent_heuristic boolean Use the indent heuristic for the internal diff library.
|
||||
--- @field algorithm? 'myers'|'minimal'|'patience'|'histogram'
|
||||
--- @field ctxlen? integer Context length
|
||||
--- @field interhunkctxlen? integer Inter hunk context length
|
||||
--- @field ignore_whitespace? boolean Ignore whitespace
|
||||
--- @field ignore_whitespace_change? boolean Ignore whitespace change
|
||||
--- @field ignore_whitespace_change_at_eol? boolean Ignore whitespace change at end-of-line.
|
||||
--- @field ignore_cr_at_eol? boolean Ignore carriage return at end-of-line
|
||||
--- @field ignore_blank_lines? boolean Ignore blank lines
|
||||
--- @field indent_heuristic? boolean Use the indent heuristic for the internal diff library.
|
||||
|
||||
-- luacheck: no unused args
|
||||
|
||||
@ -65,7 +65,7 @@
|
||||
---
|
||||
---@param a string First string to compare
|
||||
---@param b string Second string to compare
|
||||
---@param opts vim.diff.Opts
|
||||
---@param opts? vim.diff.Opts
|
||||
---@return string|integer[][]?
|
||||
--- See {opts.result_type}. `nil` if {opts.on_hunk} is given.
|
||||
function vim.diff(a, b, opts) end
|
||||
|
@ -2,7 +2,7 @@
|
||||
error('Cannot require a meta file')
|
||||
|
||||
-- These types were taken from https://github.com/LuaCATS/lpeg
|
||||
-- (based on revision e6789e28e5b91a4a277a2a03081d708c403a3e34)
|
||||
-- (based on revision 33f4ff5343a64cf613a0634d70092fbc2b64291b)
|
||||
-- with types being renamed to include the vim namespace and with some descriptions made less verbose.
|
||||
|
||||
--- @brief <pre>help
|
||||
@ -22,17 +22,18 @@ vim.lpeg = {}
|
||||
|
||||
--- @nodoc
|
||||
--- @class vim.lpeg.Pattern
|
||||
--- @operator len: vim.lpeg.Pattern
|
||||
--- @operator unm: vim.lpeg.Pattern
|
||||
--- @operator add(vim.lpeg.Pattern): vim.lpeg.Pattern
|
||||
--- @operator sub(vim.lpeg.Pattern): vim.lpeg.Pattern
|
||||
--- @operator mul(vim.lpeg.Pattern): vim.lpeg.Pattern
|
||||
--- @operator mul(vim.lpeg.Capture): vim.lpeg.Pattern
|
||||
--- @operator div(string): vim.lpeg.Capture
|
||||
--- @operator div(number): vim.lpeg.Capture
|
||||
--- @operator div(integer): vim.lpeg.Capture
|
||||
--- @operator div(table): vim.lpeg.Capture
|
||||
--- @operator div(function): vim.lpeg.Capture
|
||||
--- @operator pow(number): vim.lpeg.Pattern
|
||||
--- @operator mod(function): nil
|
||||
--- @operator pow(integer): vim.lpeg.Pattern
|
||||
--- @operator mod(function): vim.lpeg.Capture
|
||||
local Pattern = {}
|
||||
|
||||
--- @alias vim.lpeg.Capture vim.lpeg.Pattern
|
||||
@ -55,11 +56,12 @@ local Pattern = {}
|
||||
--- assert(pattern:match('1 hello') == nil)
|
||||
--- ```
|
||||
---
|
||||
--- @param pattern vim.lpeg.Pattern
|
||||
--- @param pattern vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @param subject string
|
||||
--- @param init? integer
|
||||
--- @return integer|vim.lpeg.Capture|nil
|
||||
function vim.lpeg.match(pattern, subject, init) end
|
||||
--- @param ... any
|
||||
--- @return any ...
|
||||
function vim.lpeg.match(pattern, subject, init, ...) end
|
||||
|
||||
--- Matches the given `pattern` against the `subject` string. If the match succeeds, returns the
|
||||
--- index in the subject of the first character after the match, or the captured values (if the
|
||||
@ -81,8 +83,9 @@ function vim.lpeg.match(pattern, subject, init) end
|
||||
---
|
||||
--- @param subject string
|
||||
--- @param init? integer
|
||||
--- @return integer|vim.lpeg.Capture|nil
|
||||
function Pattern:match(subject, init) end
|
||||
--- @param ... any
|
||||
--- @return any ...
|
||||
function Pattern:match(subject, init, ...) end
|
||||
|
||||
--- Returns the string `"pattern"` if the given value is a pattern, otherwise `nil`.
|
||||
---
|
||||
@ -123,7 +126,7 @@ function vim.lpeg.P(value) end
|
||||
--- Pattern `patt` must match only strings with some fixed length, and it cannot contain captures.
|
||||
--- Like the `and` predicate, this pattern never consumes any input, independently of success or failure.
|
||||
---
|
||||
--- @param pattern vim.lpeg.Pattern
|
||||
--- @param pattern vim.lpeg.Pattern|string|integer|boolean|table
|
||||
--- @return vim.lpeg.Pattern
|
||||
function vim.lpeg.B(pattern) end
|
||||
|
||||
@ -163,7 +166,7 @@ function vim.lpeg.S(string) end
|
||||
--- assert(b:match('(') == nil)
|
||||
--- ```
|
||||
---
|
||||
--- @param v string|integer
|
||||
--- @param v boolean|string|number|function|table|thread|userdata|lightuserdata
|
||||
--- @return vim.lpeg.Pattern
|
||||
function vim.lpeg.V(v) end
|
||||
|
||||
@ -227,7 +230,7 @@ function vim.lpeg.locale(tab) end
|
||||
--- assert(c == 'c')
|
||||
--- ```
|
||||
---
|
||||
--- @param patt vim.lpeg.Pattern
|
||||
--- @param patt vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @return vim.lpeg.Capture
|
||||
function vim.lpeg.C(patt) end
|
||||
|
||||
@ -258,7 +261,7 @@ function vim.lpeg.Cc(...) end
|
||||
--- `func(...func(func(C1, C2), C3)...,Cn)`, that is, it will fold (or accumulate, or reduce) the captures from
|
||||
--- `patt` using function `func`. This capture assumes that `patt` should produce at least one capture with at
|
||||
--- least one value (of any type), which becomes the initial value of an accumulator. (If you need a specific
|
||||
--- initial value, you may prefix a constant captureto `patt`.) For each subsequent capture, LPeg calls `func`
|
||||
--- initial value, you may prefix a constant capture to `patt`.) For each subsequent capture, LPeg calls `func`
|
||||
--- with this accumulator as the first argument and all values produced by the capture as extra arguments;
|
||||
--- the first result from this call becomes the new value for the accumulator. The final value of the accumulator
|
||||
--- becomes the captured value.
|
||||
@ -273,7 +276,7 @@ function vim.lpeg.Cc(...) end
|
||||
--- assert(sum:match('10,30,43') == 83)
|
||||
--- ```
|
||||
---
|
||||
--- @param patt vim.lpeg.Pattern
|
||||
--- @param patt vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @param func fun(acc, newvalue)
|
||||
--- @return vim.lpeg.Capture
|
||||
function vim.lpeg.Cf(patt, func) end
|
||||
@ -282,7 +285,7 @@ function vim.lpeg.Cf(patt, func) end
|
||||
--- The group may be anonymous (if no name is given) or named with the given name (which
|
||||
--- can be any non-nil Lua value).
|
||||
---
|
||||
--- @param patt vim.lpeg.Pattern
|
||||
--- @param patt vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @param name? string
|
||||
--- @return vim.lpeg.Capture
|
||||
function vim.lpeg.Cg(patt, name) end
|
||||
@ -320,7 +323,7 @@ function vim.lpeg.Cp() end
|
||||
--- assert(gsub('Hello, xxx!', 'xxx', 'World') == 'Hello, World!')
|
||||
--- ```
|
||||
---
|
||||
--- @param patt vim.lpeg.Pattern
|
||||
--- @param patt vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @return vim.lpeg.Capture
|
||||
function vim.lpeg.Cs(patt) end
|
||||
|
||||
@ -329,7 +332,7 @@ function vim.lpeg.Cs(patt) end
|
||||
--- Moreover, for each named capture group created by `patt`, the first value of the group is put into
|
||||
--- the table with the group name as its key. The captured value is only the table.
|
||||
---
|
||||
--- @param patt vim.lpeg.Pattern|''
|
||||
--- @param patt vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @return vim.lpeg.Capture
|
||||
function vim.lpeg.Ct(patt) end
|
||||
|
||||
@ -343,7 +346,7 @@ function vim.lpeg.Ct(patt) end
|
||||
--- (so, to return true is equivalent to return `i`). If the call returns `false`, `nil`, or no value, the match fails.
|
||||
--- Any extra values returned by the function become the values produced by the capture.
|
||||
---
|
||||
--- @param patt vim.lpeg.Pattern
|
||||
--- @param fn function
|
||||
--- @param patt vim.lpeg.Pattern|string|integer|boolean|table|function
|
||||
--- @param fn fun(s: string, i: integer, ...: any): (position: boolean|integer, ...: any)
|
||||
--- @return vim.lpeg.Capture
|
||||
function vim.lpeg.Cmt(patt, fn) end
|
||||
|
22
runtime/lua/vim/_meta/options.lua
generated
22
runtime/lua/vim/_meta/options.lua
generated
@ -544,7 +544,7 @@ vim.wo.bri = vim.wo.breakindent
|
||||
--- applying 'breakindent', even if the resulting
|
||||
--- text should normally be narrower. This prevents
|
||||
--- text indented almost to the right window border
|
||||
--- occupying lot of vertical space when broken.
|
||||
--- occupying lots of vertical space when broken.
|
||||
--- (default: 20)
|
||||
--- shift:{n} After applying 'breakindent', the wrapped line's
|
||||
--- beginning will be shifted by the given number of
|
||||
@ -3330,7 +3330,7 @@ vim.go.is = vim.go.incsearch
|
||||
--- in Insert mode as specified with the 'indentkeys' option.
|
||||
--- When this option is not empty, it overrules the 'cindent' and
|
||||
--- 'smartindent' indenting. When 'lisp' is set, this option is
|
||||
--- is only used when 'lispoptions' contains "expr:1".
|
||||
--- only used when 'lispoptions' contains "expr:1".
|
||||
--- The expression is evaluated with `v:lnum` set to the line number for
|
||||
--- which the indent is to be computed. The cursor is also in this line
|
||||
--- when the expression is evaluated (but it may be moved around).
|
||||
@ -3541,8 +3541,11 @@ vim.go.js = vim.go.joinspaces
|
||||
--- |alternate-file` or using `mark-motions` try to
|
||||
--- restore the `mark-view` in which the action occurred.
|
||||
---
|
||||
--- clean Remove unloaded buffers from the jumplist.
|
||||
--- EXPERIMENTAL: this flag may change in the future.
|
||||
---
|
||||
--- @type string
|
||||
vim.o.jumpoptions = ""
|
||||
vim.o.jumpoptions = "clean"
|
||||
vim.o.jop = vim.o.jumpoptions
|
||||
vim.go.jumpoptions = vim.o.jumpoptions
|
||||
vim.go.jop = vim.go.jumpoptions
|
||||
@ -3628,7 +3631,7 @@ vim.go.kp = vim.go.keywordprg
|
||||
--- part can be in one of two forms:
|
||||
--- 1. A list of pairs. Each pair is a "from" character immediately
|
||||
--- followed by the "to" character. Examples: "aA", "aAbBcC".
|
||||
--- 2. A list of "from" characters, a semi-colon and a list of "to"
|
||||
--- 2. A list of "from" characters, a semicolon and a list of "to"
|
||||
--- characters. Example: "abc;ABC"
|
||||
--- Example: "aA,fgh;FGH,cCdDeE"
|
||||
--- Special characters need to be preceded with a backslash. These are
|
||||
@ -3720,7 +3723,7 @@ vim.go.ls = vim.go.laststatus
|
||||
--- update use `:redraw`.
|
||||
--- This may occasionally cause display errors. It is only meant to be set
|
||||
--- temporarily when performing an operation where redrawing may cause
|
||||
--- flickering or cause a slow down.
|
||||
--- flickering or cause a slowdown.
|
||||
---
|
||||
--- @type boolean
|
||||
vim.o.lazyredraw = false
|
||||
@ -3820,6 +3823,9 @@ vim.go.lw = vim.go.lispwords
|
||||
--- between tabs and spaces and for trailing blanks. Further changed by
|
||||
--- the 'listchars' option.
|
||||
---
|
||||
--- When 'listchars' does not contain "tab" field, tabs are shown as "^I"
|
||||
--- or "<09>", like how unprintable characters are displayed.
|
||||
---
|
||||
--- The cursor is displayed at the start of the space a Tab character
|
||||
--- occupies, not at the end as usual in Normal mode. To get this cursor
|
||||
--- position while displaying Tabs with spaces, use:
|
||||
@ -4757,7 +4763,7 @@ vim.go.pm = vim.go.patchmode
|
||||
--- ```
|
||||
--- To use an environment variable, you probably need to replace the
|
||||
--- separator. Here is an example to append $INCL, in which directory
|
||||
--- names are separated with a semi-colon:
|
||||
--- names are separated with a semicolon:
|
||||
---
|
||||
--- ```vim
|
||||
--- let &path = &path .. "," .. substitute($INCL, ';', ',', 'g')
|
||||
@ -5764,7 +5770,7 @@ vim.bo.shiftwidth = vim.o.shiftwidth
|
||||
vim.bo.sw = vim.bo.shiftwidth
|
||||
|
||||
--- This option helps to avoid all the `hit-enter` prompts caused by file
|
||||
--- messages, for example with CTRL-G, and to avoid some other messages.
|
||||
--- messages, for example with CTRL-G, and to avoid some other messages.
|
||||
--- It is a list of flags:
|
||||
--- flag meaning when present ~
|
||||
--- l use "999L, 888B" instead of "999 lines, 888 bytes" *shm-l*
|
||||
@ -6249,7 +6255,7 @@ vim.bo.spo = vim.bo.spelloptions
|
||||
--- minus two.
|
||||
---
|
||||
--- timeout:{millisec} Limit the time searching for suggestions to
|
||||
--- {millisec} milli seconds. Applies to the following
|
||||
--- {millisec} milliseconds. Applies to the following
|
||||
--- methods. When omitted the limit is 5000. When
|
||||
--- negative there is no limit.
|
||||
---
|
||||
|
42
runtime/lua/vim/_meta/vimfn.lua
generated
42
runtime/lua/vim/_meta/vimfn.lua
generated
@ -2823,7 +2823,7 @@ function vim.fn.getcharpos(expr) end
|
||||
--- nnoremap <expr> , getcharsearch().forward ? ',' : ';'
|
||||
--- <Also see |setcharsearch()|.
|
||||
---
|
||||
--- @return table[]
|
||||
--- @return table
|
||||
function vim.fn.getcharsearch() end
|
||||
|
||||
--- Get a single character from the user or input stream as a
|
||||
@ -3569,8 +3569,8 @@ function vim.fn.getreginfo(regname) end
|
||||
--- difference if the buffer is displayed in a window with
|
||||
--- different 'virtualedit' or 'list' values.
|
||||
---
|
||||
--- Examples: >
|
||||
--- :xnoremap <CR>
|
||||
--- Examples: >vim
|
||||
--- xnoremap <CR>
|
||||
--- \ <Cmd>echom getregion(
|
||||
--- \ getpos('v'), getpos('.'), #{ type: mode() })<CR>
|
||||
--- <
|
||||
@ -4233,7 +4233,7 @@ function vim.fn.iconv(string, from, to) end
|
||||
--- Note that `v:_null_string`, `v:_null_list`, `v:_null_dict` and
|
||||
--- `v:_null_blob` have the same `id()` with different types
|
||||
--- because they are internally represented as NULL pointers.
|
||||
--- `id()` returns a hexadecimal representanion of the pointers to
|
||||
--- `id()` returns a hexadecimal representation of the pointers to
|
||||
--- the containers (i.e. like `0x994a40`), same as `printf("%p",
|
||||
--- {expr})`, but it is advised against counting on the exact
|
||||
--- format of the return value.
|
||||
@ -5538,19 +5538,19 @@ function vim.fn.matcharg(nr) end
|
||||
---
|
||||
--- Examples: >vim
|
||||
--- " Assuming line 3 in buffer 5 contains "a"
|
||||
--- :echo matchbufline(5, '\<\k\+\>', 3, 3)
|
||||
--- [{'lnum': 3, 'byteidx': 0, 'text': 'a'}]
|
||||
--- echo matchbufline(5, '\<\k\+\>', 3, 3)
|
||||
--- < `[{'lnum': 3, 'byteidx': 0, 'text': 'a'}]` >vim
|
||||
--- " Assuming line 4 in buffer 10 contains "tik tok"
|
||||
--- :echo matchbufline(10, '\<\k\+\>', 1, 4)
|
||||
--- [{'lnum': 4, 'byteidx': 0, 'text': 'tik'}, {'lnum': 4, 'byteidx': 4, 'text': 'tok'}]
|
||||
--- <
|
||||
--- echo matchbufline(10, '\<\k\+\>', 1, 4)
|
||||
--- < `[{'lnum': 4, 'byteidx': 0, 'text': 'tik'}, {'lnum': 4, 'byteidx': 4, 'text': 'tok'}]`
|
||||
---
|
||||
--- If {submatch} is present and is v:true, then submatches like
|
||||
--- "\1", "\2", etc. are also returned. Example: >vim
|
||||
--- " Assuming line 2 in buffer 2 contains "acd"
|
||||
--- :echo matchbufline(2, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2, 2
|
||||
--- echo matchbufline(2, '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2, 2
|
||||
--- \ {'submatches': v:true})
|
||||
--- [{'lnum': 2, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]
|
||||
--- <The "submatches" List always contains 9 items. If a submatch
|
||||
--- < `[{'lnum': 2, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]`
|
||||
--- The "submatches" List always contains 9 items. If a submatch
|
||||
--- is not found, then an empty string is returned for that
|
||||
--- submatch.
|
||||
---
|
||||
@ -5749,17 +5749,17 @@ function vim.fn.matchstr(expr, pat, start, count) end
|
||||
--- option settings on the pattern.
|
||||
---
|
||||
--- Example: >vim
|
||||
--- :echo matchstrlist(['tik tok'], '\<\k\+\>')
|
||||
--- [{'idx': 0, 'byteidx': 0, 'text': 'tik'}, {'idx': 0, 'byteidx': 4, 'text': 'tok'}]
|
||||
--- :echo matchstrlist(['a', 'b'], '\<\k\+\>')
|
||||
--- [{'idx': 0, 'byteidx': 0, 'text': 'a'}, {'idx': 1, 'byteidx': 0, 'text': 'b'}]
|
||||
--- <
|
||||
--- echo matchstrlist(['tik tok'], '\<\k\+\>')
|
||||
--- < `[{'idx': 0, 'byteidx': 0, 'text': 'tik'}, {'idx': 0, 'byteidx': 4, 'text': 'tok'}]` >vim
|
||||
--- echo matchstrlist(['a', 'b'], '\<\k\+\>')
|
||||
--- < `[{'idx': 0, 'byteidx': 0, 'text': 'a'}, {'idx': 1, 'byteidx': 0, 'text': 'b'}]`
|
||||
---
|
||||
--- If "submatches" is present and is v:true, then submatches like
|
||||
--- "\1", "\2", etc. are also returned. Example: >vim
|
||||
--- :echo matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)',
|
||||
--- echo matchstrlist(['acd'], '\(a\)\?\(b\)\?\(c\)\?\(.*\)',
|
||||
--- \ #{submatches: v:true})
|
||||
--- [{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]
|
||||
--- <The "submatches" List always contains 9 items. If a submatch
|
||||
--- < `[{'idx': 0, 'byteidx': 0, 'text': 'acd', 'submatches': ['a', '', 'c', 'd', '', '', '', '', '']}]`
|
||||
--- The "submatches" List always contains 9 items. If a submatch
|
||||
--- is not found, then an empty string is returned for that
|
||||
--- submatch.
|
||||
---
|
||||
@ -7199,7 +7199,7 @@ function vim.fn.screenchars(row, col) end
|
||||
--- the following mappings: >vim
|
||||
--- nnoremap <expr> GG ":echom " .. screencol() .. "\n"
|
||||
--- nnoremap <silent> GG :echom screencol()<CR>
|
||||
--- noremap GG <Cmd>echom screencol()<Cr>
|
||||
--- noremap GG <Cmd>echom screencol()<CR>
|
||||
--- <
|
||||
---
|
||||
--- @return any
|
||||
|
@ -276,11 +276,9 @@ vim.go = setmetatable({}, {
|
||||
})
|
||||
|
||||
--- Get or set buffer-scoped |options| for the buffer with number {bufnr}.
|
||||
--- If {bufnr} is omitted then the current buffer is used.
|
||||
--- Like `:setlocal`. If {bufnr} is omitted then the current buffer is used.
|
||||
--- Invalid {bufnr} or key is an error.
|
||||
---
|
||||
--- Note: this is equivalent to `:setlocal` for |global-local| options and `:set` otherwise.
|
||||
---
|
||||
--- Example:
|
||||
---
|
||||
--- ```lua
|
||||
|
@ -88,7 +88,8 @@ function SystemObj:_timeout(signal)
|
||||
self:kill(signal or SIG.TERM)
|
||||
end
|
||||
|
||||
local MAX_TIMEOUT = 2 ^ 31
|
||||
-- Use max 32-bit signed int value to avoid overflow on 32-bit systems. #31633
|
||||
local MAX_TIMEOUT = 2 ^ 31 - 1
|
||||
|
||||
--- @param timeout? integer
|
||||
--- @return vim.SystemCompleted
|
||||
|
@ -1239,6 +1239,10 @@ M.handlers.signs = {
|
||||
bufnr = get_bufnr(bufnr)
|
||||
opts = opts or {}
|
||||
|
||||
if not api.nvim_buf_is_loaded(bufnr) then
|
||||
return
|
||||
end
|
||||
|
||||
if opts.signs and opts.signs.severity then
|
||||
diagnostics = filter_by_severity(opts.signs.severity, diagnostics)
|
||||
end
|
||||
@ -1323,8 +1327,10 @@ M.handlers.signs = {
|
||||
local numhl = opts.signs.numhl or {}
|
||||
local linehl = opts.signs.linehl or {}
|
||||
|
||||
local line_count = api.nvim_buf_line_count(bufnr)
|
||||
|
||||
for _, diagnostic in ipairs(diagnostics) do
|
||||
if api.nvim_buf_is_loaded(diagnostic.bufnr) then
|
||||
if diagnostic.lnum <= line_count then
|
||||
api.nvim_buf_set_extmark(bufnr, ns.user_data.sign_ns, diagnostic.lnum, 0, {
|
||||
sign_text = text[diagnostic.severity] or text[M.severity[diagnostic.severity]] or 'U',
|
||||
sign_hl_group = sign_highlight_map[diagnostic.severity],
|
||||
|
@ -144,6 +144,9 @@ end
|
||||
|
||||
local function detect_noext(path, bufnr)
|
||||
local root = fn.fnamemodify(path, ':r')
|
||||
if root == path then
|
||||
return
|
||||
end
|
||||
return M.match({ buf = bufnr, filename = root })
|
||||
end
|
||||
|
||||
@ -1258,8 +1261,7 @@ local extension = {
|
||||
['dpkg-new'] = detect_noext,
|
||||
['in'] = function(path, bufnr)
|
||||
if vim.fs.basename(path) ~= 'configure.in' then
|
||||
local root = fn.fnamemodify(path, ':r')
|
||||
return M.match({ buf = bufnr, filename = root })
|
||||
return detect_noext(path, bufnr)
|
||||
end
|
||||
end,
|
||||
new = detect_noext,
|
||||
|
@ -594,7 +594,7 @@ function M.frm(_, bufnr)
|
||||
end
|
||||
|
||||
--- @type vim.filetype.mapfn
|
||||
function M.fvwm_1(_, _)
|
||||
function M.fvwm_v1(_, _)
|
||||
return 'fvwm', function(bufnr)
|
||||
vim.b[bufnr].fvwm_version = 1
|
||||
end
|
||||
@ -1331,7 +1331,7 @@ end
|
||||
function M.sgml(_, bufnr)
|
||||
local lines = table.concat(getlines(bufnr, 1, 5))
|
||||
if lines:find('linuxdoc') then
|
||||
return 'smgllnx'
|
||||
return 'sgmllnx'
|
||||
elseif lines:find('<!DOCTYPE.*DocBook') then
|
||||
return 'docbk',
|
||||
function(b)
|
||||
|
@ -1,6 +1,8 @@
|
||||
local M = {}
|
||||
|
||||
local iswin = vim.uv.os_uname().sysname == 'Windows_NT'
|
||||
-- Can't use `has('win32')` because the `nvim -ll` test runner doesn't support `vim.fn` yet.
|
||||
local sysname = vim.uv.os_uname().sysname:lower()
|
||||
local iswin = not not (sysname:find('windows') or sysname:find('mingw'))
|
||||
local os_sep = iswin and '\\' or '/'
|
||||
|
||||
--- Iterate over all the parents of the given path.
|
||||
@ -328,8 +330,11 @@ function M.find(names, opts)
|
||||
return matches
|
||||
end
|
||||
|
||||
--- Find the first parent directory containing a specific "marker", relative to a buffer's
|
||||
--- directory.
|
||||
--- Find the first parent directory containing a specific "marker", relative to a file path or
|
||||
--- buffer.
|
||||
---
|
||||
--- If the buffer is unnamed (has no backing file) or has a non-empty 'buftype' then the search
|
||||
--- begins from Nvim's |current-directory|.
|
||||
---
|
||||
--- Example:
|
||||
---
|
||||
@ -346,13 +351,13 @@ end
|
||||
--- end)
|
||||
--- ```
|
||||
---
|
||||
--- @param source integer|string Buffer number (0 for current buffer) or file path to begin the
|
||||
--- search from.
|
||||
--- @param source integer|string Buffer number (0 for current buffer) or file path (absolute or
|
||||
--- relative to the |current-directory|) to begin the search from.
|
||||
--- @param marker (string|string[]|fun(name: string, path: string): boolean) A marker, or list
|
||||
--- of markers, to search for. If a function, the function is called for each
|
||||
--- evaluated item and should return true if {name} and {path} are a match.
|
||||
--- @return string? # Directory path containing one of the given markers, or nil if no directory was
|
||||
--- found.
|
||||
--- found.
|
||||
function M.root(source, marker)
|
||||
assert(source, 'missing required argument: source')
|
||||
assert(marker, 'missing required argument: marker')
|
||||
@ -361,14 +366,18 @@ function M.root(source, marker)
|
||||
if type(source) == 'string' then
|
||||
path = source
|
||||
elseif type(source) == 'number' then
|
||||
path = vim.api.nvim_buf_get_name(source)
|
||||
if vim.bo[source].buftype ~= '' then
|
||||
path = assert(vim.uv.cwd())
|
||||
else
|
||||
path = vim.api.nvim_buf_get_name(source)
|
||||
end
|
||||
else
|
||||
error('invalid type for argument "source": expected string or buffer number')
|
||||
end
|
||||
|
||||
local paths = M.find(marker, {
|
||||
upward = true,
|
||||
path = path,
|
||||
path = vim.fn.fnamemodify(path, ':p:h'),
|
||||
})
|
||||
|
||||
if #paths == 0 then
|
||||
|
@ -13,7 +13,7 @@ local function filepath_to_healthcheck(path)
|
||||
func = 'health#' .. name .. '#check'
|
||||
filetype = 'v'
|
||||
else
|
||||
local subpath = path:gsub('.*lua/', '')
|
||||
local subpath = path:gsub('.*/lua/', '')
|
||||
if vim.fs.basename(subpath) == 'health.lua' then
|
||||
-- */health.lua
|
||||
name = assert(vim.fs.dirname(subpath))
|
||||
@ -306,7 +306,7 @@ function M.system(cmd, args)
|
||||
|
||||
if jobid < 1 then
|
||||
local message =
|
||||
string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.loop.cwd())
|
||||
string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.uv.cwd())
|
||||
error(message)
|
||||
return opts.output, 1
|
||||
end
|
||||
@ -325,7 +325,7 @@ function M.system(cmd, args)
|
||||
jobid,
|
||||
shell_error_code,
|
||||
shellify(cmd),
|
||||
vim.loop.cwd()
|
||||
vim.uv.cwd()
|
||||
)
|
||||
if opts.output:find('%S') then
|
||||
emsg = string.format('%s\noutput: %s', emsg, opts.output)
|
||||
@ -350,8 +350,8 @@ local path2name = function(path)
|
||||
-- Remove everything up to the last /lua/ folder
|
||||
path = path:gsub('^.*/lua/', '')
|
||||
|
||||
-- Remove the filename (health.lua)
|
||||
path = vim.fs.dirname(path)
|
||||
-- Remove the filename (health.lua) or (health/init.lua)
|
||||
path = vim.fs.dirname(path:gsub('/init%.lua$', ''))
|
||||
|
||||
-- Change slashes to dots
|
||||
path = path:gsub('/', '.')
|
||||
|
@ -208,8 +208,7 @@ end
|
||||
---@return string|function
|
||||
---@private
|
||||
function Loader.loader_lib(modname)
|
||||
local sysname = uv.os_uname().sysname:lower() or ''
|
||||
local is_win = sysname:find('win', 1, true) and not sysname:find('darwin', 1, true)
|
||||
local is_win = vim.fn.has('win32') == 1
|
||||
local ret = M.find(modname, { patterns = is_win and { '.dll' } or { '.so' } })[1]
|
||||
if ret then
|
||||
-- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
|
||||
|
@ -64,6 +64,8 @@ lsp._request_name_to_capability = {
|
||||
[ms.textDocument_inlayHint] = { 'inlayHintProvider' },
|
||||
[ms.textDocument_diagnostic] = { 'diagnosticProvider' },
|
||||
[ms.inlayHint_resolve] = { 'inlayHintProvider', 'resolveProvider' },
|
||||
[ms.textDocument_documentLink] = { 'documentLinkProvider' },
|
||||
[ms.documentLink_resolve] = { 'documentLinkProvider', 'resolveProvider' },
|
||||
}
|
||||
|
||||
-- TODO improve handling of scratch buffers with LSP attached.
|
||||
@ -373,7 +375,7 @@ local function reset_defaults(bufnr)
|
||||
end
|
||||
api.nvim_buf_call(bufnr, function()
|
||||
local keymap = vim.fn.maparg('K', 'n', false, true)
|
||||
if keymap and keymap.callback == vim.lsp.buf.hover then
|
||||
if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
|
||||
vim.keymap.del('n', 'K', { buffer = bufnr })
|
||||
end
|
||||
end)
|
||||
@ -385,8 +387,8 @@ end
|
||||
local function on_client_exit(code, signal, client_id)
|
||||
local client = all_clients[client_id]
|
||||
|
||||
for bufnr in pairs(client.attached_buffers) do
|
||||
vim.schedule(function()
|
||||
vim.schedule(function()
|
||||
for bufnr in pairs(client.attached_buffers) do
|
||||
if client and client.attached_buffers[bufnr] then
|
||||
api.nvim_exec_autocmds('LspDetach', {
|
||||
buffer = bufnr,
|
||||
@ -395,15 +397,16 @@ local function on_client_exit(code, signal, client_id)
|
||||
})
|
||||
end
|
||||
|
||||
local namespace = vim.lsp.diagnostic.get_namespace(client_id)
|
||||
vim.diagnostic.reset(namespace, bufnr)
|
||||
client.attached_buffers[bufnr] = nil
|
||||
|
||||
if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
|
||||
reset_defaults(bufnr)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local namespace = vim.lsp.diagnostic.get_namespace(client_id)
|
||||
vim.diagnostic.reset(namespace)
|
||||
end)
|
||||
|
||||
local name = client.name or 'unknown'
|
||||
|
||||
@ -495,6 +498,29 @@ local function text_document_did_save_handler(bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
---@param bufnr integer resolved buffer
|
||||
---@param client vim.lsp.Client
|
||||
local function buf_detach_client(bufnr, client)
|
||||
api.nvim_exec_autocmds('LspDetach', {
|
||||
buffer = bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client.id },
|
||||
})
|
||||
|
||||
changetracking.reset_buf(client, bufnr)
|
||||
|
||||
if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then
|
||||
local uri = vim.uri_from_bufnr(bufnr)
|
||||
local params = { textDocument = { uri = uri } }
|
||||
client.notify(ms.textDocument_didClose, params)
|
||||
end
|
||||
|
||||
client.attached_buffers[bufnr] = nil
|
||||
|
||||
local namespace = lsp.diagnostic.get_namespace(client.id)
|
||||
vim.diagnostic.reset(namespace, bufnr)
|
||||
end
|
||||
|
||||
--- @type table<integer,true>
|
||||
local attached_buffers = {}
|
||||
|
||||
@ -547,36 +573,34 @@ local function buf_attach(bufnr)
|
||||
api.nvim_buf_attach(bufnr, false, {
|
||||
on_lines = function(_, _, changedtick, firstline, lastline, new_lastline)
|
||||
if #lsp.get_clients({ bufnr = bufnr }) == 0 then
|
||||
return true -- detach
|
||||
-- detach if there are no clients
|
||||
return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0
|
||||
end
|
||||
util.buf_versions[bufnr] = changedtick
|
||||
changetracking.send_changes(bufnr, firstline, lastline, new_lastline)
|
||||
end,
|
||||
|
||||
on_reload = function()
|
||||
local clients = lsp.get_clients({ bufnr = bufnr })
|
||||
local params = { textDocument = { uri = uri } }
|
||||
for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do
|
||||
for _, client in ipairs(clients) do
|
||||
changetracking.reset_buf(client, bufnr)
|
||||
if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then
|
||||
client.notify(ms.textDocument_didClose, params)
|
||||
end
|
||||
end
|
||||
for _, client in ipairs(clients) do
|
||||
client:_text_document_did_open_handler(bufnr)
|
||||
end
|
||||
end,
|
||||
|
||||
on_detach = function()
|
||||
local params = { textDocument = { uri = uri } }
|
||||
for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do
|
||||
changetracking.reset_buf(client, bufnr)
|
||||
if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then
|
||||
client.notify(ms.textDocument_didClose, params)
|
||||
end
|
||||
local clients = lsp.get_clients({ bufnr = bufnr, _uninitialized = true })
|
||||
for _, client in ipairs(clients) do
|
||||
buf_detach_client(bufnr, client)
|
||||
end
|
||||
for _, client in ipairs(all_clients) do
|
||||
client.attached_buffers[bufnr] = nil
|
||||
end
|
||||
util.buf_versions[bufnr] = nil
|
||||
attached_buffers[bufnr] = nil
|
||||
util.buf_versions[bufnr] = nil
|
||||
end,
|
||||
|
||||
-- TODO if we know all of the potential clients ahead of time, then we
|
||||
@ -650,27 +674,9 @@ function lsp.buf_detach_client(bufnr, client_id)
|
||||
)
|
||||
)
|
||||
return
|
||||
else
|
||||
buf_detach_client(bufnr, client)
|
||||
end
|
||||
|
||||
api.nvim_exec_autocmds('LspDetach', {
|
||||
buffer = bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client_id },
|
||||
})
|
||||
|
||||
changetracking.reset_buf(client, bufnr)
|
||||
|
||||
if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then
|
||||
local uri = vim.uri_from_bufnr(bufnr)
|
||||
local params = { textDocument = { uri = uri } }
|
||||
client.notify(ms.textDocument_didClose, params)
|
||||
end
|
||||
|
||||
client.attached_buffers[bufnr] = nil
|
||||
util.buf_versions[bufnr] = nil
|
||||
|
||||
local namespace = lsp.diagnostic.get_namespace(client_id)
|
||||
vim.diagnostic.reset(namespace, bufnr)
|
||||
end
|
||||
|
||||
--- Checks if a buffer is attached for a particular client.
|
||||
@ -844,17 +850,20 @@ api.nvim_create_autocmd('VimLeavePre', {
|
||||
---@param params table|nil Parameters to send to the server
|
||||
---@param handler? lsp.Handler See |lsp-handler|
|
||||
--- If nil, follows resolution strategy defined in |lsp-handler-configuration|
|
||||
---
|
||||
---@param on_unsupported? fun()
|
||||
--- The function to call when the buffer has no clients that support the given method.
|
||||
--- Defaults to an `ERROR` level notification.
|
||||
---@return table<integer, integer> client_request_ids Map of client-id:request-id pairs
|
||||
---for all successful requests.
|
||||
---@return function _cancel_all_requests Function which can be used to
|
||||
---cancel all the requests. You could instead
|
||||
---iterate all clients and call their `cancel_request()` methods.
|
||||
function lsp.buf_request(bufnr, method, params, handler)
|
||||
function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
|
||||
validate({
|
||||
bufnr = { bufnr, 'n', true },
|
||||
method = { method, 's' },
|
||||
handler = { handler, 'f', true },
|
||||
on_unsupported = { on_unsupported, 'f', true },
|
||||
})
|
||||
|
||||
bufnr = resolve_bufnr(bufnr)
|
||||
@ -876,7 +885,11 @@ function lsp.buf_request(bufnr, method, params, handler)
|
||||
|
||||
-- if has client but no clients support the given method, notify the user
|
||||
if next(clients) and not method_supported then
|
||||
vim.notify(lsp._unsupported_method(method), vim.log.levels.ERROR)
|
||||
if on_unsupported == nil then
|
||||
vim.notify(lsp._unsupported_method(method), vim.log.levels.ERROR)
|
||||
else
|
||||
on_unsupported()
|
||||
end
|
||||
vim.cmd.redraw()
|
||||
return {}, function() end
|
||||
end
|
||||
|
@ -448,7 +448,7 @@ local function pick_call_hierarchy_item(call_hierarchy_items)
|
||||
if choice < 1 or choice > #items then
|
||||
return
|
||||
end
|
||||
return choice
|
||||
return call_hierarchy_items[choice]
|
||||
end
|
||||
|
||||
--- @param method string
|
||||
@ -836,14 +836,10 @@ function M.code_action(opts)
|
||||
if opts.diagnostics or opts.only then
|
||||
opts = { options = opts }
|
||||
end
|
||||
local context = opts.context or {}
|
||||
local context = opts.context and vim.deepcopy(opts.context) or {}
|
||||
if not context.triggerKind then
|
||||
context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked
|
||||
end
|
||||
if not context.diagnostics then
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(bufnr)
|
||||
end
|
||||
local mode = api.nvim_get_mode().mode
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local win = api.nvim_get_current_win()
|
||||
@ -885,7 +881,23 @@ function M.code_action(opts)
|
||||
else
|
||||
params = util.make_range_params(win, client.offset_encoding)
|
||||
end
|
||||
params.context = context
|
||||
if context.diagnostics then
|
||||
params.context = context
|
||||
else
|
||||
local ns_push = vim.lsp.diagnostic.get_namespace(client.id, false)
|
||||
local ns_pull = vim.lsp.diagnostic.get_namespace(client.id, true)
|
||||
local diagnostics = {}
|
||||
local lnum = api.nvim_win_get_cursor(0)[1] - 1
|
||||
vim.list_extend(diagnostics, vim.diagnostic.get(bufnr, { namespace = ns_pull, lnum = lnum }))
|
||||
vim.list_extend(diagnostics, vim.diagnostic.get(bufnr, { namespace = ns_push, lnum = lnum }))
|
||||
params.context = vim.tbl_extend('force', context, {
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
diagnostics = vim.tbl_map(function(d)
|
||||
return d.user_data.lsp
|
||||
end, diagnostics),
|
||||
})
|
||||
end
|
||||
|
||||
client.request(ms.textDocument_codeAction, params, on_result, bufnr)
|
||||
end
|
||||
end
|
||||
|
@ -182,7 +182,7 @@ local validate = vim.validate
|
||||
--- It can be `null` if the client supports workspace folders but none are
|
||||
--- configured.
|
||||
--- @field workspace_folders lsp.WorkspaceFolder[]?
|
||||
--- @field root_dir string
|
||||
--- @field root_dir string?
|
||||
---
|
||||
--- @field attached_buffers table<integer,true>
|
||||
---
|
||||
@ -470,7 +470,6 @@ function Client.create(config)
|
||||
_on_exit_cbs = ensure_list(config.on_exit),
|
||||
_on_attach_cbs = ensure_list(config.on_attach),
|
||||
_on_error_cb = config.on_error,
|
||||
_root_dir = config.root_dir,
|
||||
_trace = get_trace(config.trace),
|
||||
|
||||
--- Contains $/progress report messages.
|
||||
@ -612,7 +611,10 @@ function Client:initialize()
|
||||
self:_run_callbacks(self._on_init_cbs, lsp.client_errors.ON_INIT_CALLBACK_ERROR, self, result)
|
||||
|
||||
for buf in pairs(reattach_bufs) do
|
||||
self:_on_attach(buf)
|
||||
-- The buffer may have been detached in the on_init callback.
|
||||
if self.attached_buffers[buf] then
|
||||
self:_on_attach(buf)
|
||||
end
|
||||
end
|
||||
|
||||
log.info(
|
||||
|
@ -164,7 +164,7 @@ function M.display(lenses, bufnr, client_id)
|
||||
return a.range.start.character < b.range.start.character
|
||||
end)
|
||||
for j, lens in ipairs(line_lenses) do
|
||||
local text = lens.command and lens.command.title or 'Unresolved lens ...'
|
||||
local text = (lens.command and lens.command.title or 'Unresolved lens ...'):gsub('%s+', ' ')
|
||||
table.insert(chunks, { text, 'LspCodeLens' })
|
||||
if j < num_line_lenses then
|
||||
table.insert(chunks, { ' | ', 'LspCodeLensSeparator' })
|
||||
@ -307,7 +307,13 @@ function M.refresh(opts)
|
||||
}
|
||||
active_refreshes[buf] = true
|
||||
|
||||
local request_ids = vim.lsp.buf_request(buf, ms.textDocument_codeLens, params, M.on_codelens)
|
||||
local request_ids = vim.lsp.buf_request(
|
||||
buf,
|
||||
ms.textDocument_codeLens,
|
||||
params,
|
||||
M.on_codelens,
|
||||
function() end
|
||||
)
|
||||
if vim.tbl_isempty(request_ids) then
|
||||
active_refreshes[buf] = nil
|
||||
end
|
||||
|
@ -122,13 +122,7 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
|
||||
code = diagnostic.code,
|
||||
_tags = tags_lsp_to_vim(diagnostic, client_id),
|
||||
user_data = {
|
||||
lsp = {
|
||||
-- usage of user_data.lsp.code is deprecated in favor of the top-level code field
|
||||
code = diagnostic.code,
|
||||
codeDescription = diagnostic.codeDescription,
|
||||
relatedInformation = diagnostic.relatedInformation,
|
||||
data = diagnostic.data,
|
||||
},
|
||||
lsp = diagnostic,
|
||||
},
|
||||
}
|
||||
end, diagnostics)
|
||||
@ -157,8 +151,11 @@ local function diagnostic_vim_to_lsp(diagnostics)
|
||||
---@param diagnostic vim.Diagnostic
|
||||
---@return lsp.Diagnostic
|
||||
return vim.tbl_map(function(diagnostic)
|
||||
return vim.tbl_extend('keep', {
|
||||
-- "keep" the below fields over any duplicate fields in diagnostic.user_data.lsp
|
||||
local user_data = diagnostic.user_data or {}
|
||||
if user_data.lsp then
|
||||
return user_data.lsp
|
||||
end
|
||||
return {
|
||||
range = {
|
||||
start = {
|
||||
line = diagnostic.lnum,
|
||||
@ -174,7 +171,7 @@ local function diagnostic_vim_to_lsp(diagnostics)
|
||||
source = diagnostic.source,
|
||||
code = diagnostic.code,
|
||||
tags = tags_vim_to_lsp(diagnostic),
|
||||
}, diagnostic.user_data and (diagnostic.user_data.lsp or {}) or {})
|
||||
}
|
||||
end, diagnostics)
|
||||
end
|
||||
|
||||
@ -318,11 +315,19 @@ end
|
||||
--- )
|
||||
--- ```
|
||||
---
|
||||
---@param _ lsp.ResponseError?
|
||||
---@param error lsp.ResponseError?
|
||||
---@param result lsp.DocumentDiagnosticReport
|
||||
---@param ctx lsp.HandlerContext
|
||||
---@param config vim.diagnostic.Opts Configuration table (see |vim.diagnostic.config()|).
|
||||
function M.on_diagnostic(_, result, ctx, config)
|
||||
function M.on_diagnostic(error, result, ctx, config)
|
||||
if error ~= nil and error.code == protocol.ErrorCodes.ServerCancelled then
|
||||
if error.data == nil or error.data.retriggerRequest ~= false then
|
||||
local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
|
||||
client.request(ctx.method, ctx.params)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if result == nil or result.kind == 'unchanged' then
|
||||
return
|
||||
end
|
||||
@ -366,6 +371,7 @@ end
|
||||
--- Structured: { [1] = {...}, [5] = {.... } }
|
||||
---@private
|
||||
function M.get_line_diagnostics(bufnr, line_nr, opts, client_id)
|
||||
vim.deprecate('vim.lsp.diagnostic.get_line_diagnostics', 'vim.diagnostic.get', '0.12')
|
||||
convert_severity(opts)
|
||||
local diag_opts = {} --- @type vim.diagnostic.GetOpts
|
||||
|
||||
|
@ -716,7 +716,8 @@ for k, fn in pairs(M) do
|
||||
})
|
||||
end
|
||||
|
||||
if err then
|
||||
-- ServerCancelled errors should be propagated to the request handler
|
||||
if err and err.code ~= protocol.ErrorCodes.ServerCancelled then
|
||||
-- LSP spec:
|
||||
-- interface ResponseError:
|
||||
-- code: integer;
|
||||
|
@ -33,16 +33,25 @@ local function check_active_clients()
|
||||
local clients = vim.lsp.get_clients()
|
||||
if next(clients) then
|
||||
for _, client in pairs(clients) do
|
||||
local attached_to = table.concat(vim.tbl_keys(client.attached_buffers or {}), ',')
|
||||
report_info(
|
||||
local cmd ---@type string
|
||||
if type(client.config.cmd) == 'table' then
|
||||
cmd = table.concat(client.config.cmd --[[@as table]], ' ')
|
||||
elseif type(client.config.cmd) == 'function' then
|
||||
cmd = tostring(client.config.cmd)
|
||||
end
|
||||
report_info(table.concat({
|
||||
string.format('%s (id: %d)', client.name, client.id),
|
||||
string.format(
|
||||
'%s (id=%s, root_dir=%s, attached_to=[%s])',
|
||||
client.name,
|
||||
client.id,
|
||||
vim.fn.fnamemodify(client.root_dir, ':~'),
|
||||
attached_to
|
||||
)
|
||||
)
|
||||
' Root directory: %s',
|
||||
client.root_dir and vim.fn.fnamemodify(client.root_dir, ':~') or nil
|
||||
),
|
||||
string.format(' Command: %s', cmd),
|
||||
string.format(' Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
|
||||
string.format(
|
||||
' Attached buffers: %s',
|
||||
vim.iter(pairs(client.attached_buffers)):map(tostring):join(', ')
|
||||
),
|
||||
}, '\n'))
|
||||
end
|
||||
else
|
||||
report_info('No active clients')
|
||||
@ -50,7 +59,7 @@ local function check_active_clients()
|
||||
end
|
||||
|
||||
local function check_watcher()
|
||||
vim.health.start('vim.lsp: File watcher')
|
||||
vim.health.start('vim.lsp: File Watcher')
|
||||
|
||||
-- Only run the check if file watching has been enabled by a client.
|
||||
local clients = vim.lsp.get_clients()
|
||||
@ -94,11 +103,68 @@ local function check_watcher()
|
||||
end
|
||||
end
|
||||
|
||||
local function check_position_encodings()
|
||||
vim.health.start('vim.lsp: Position Encodings')
|
||||
local clients = vim.lsp.get_clients()
|
||||
if next(clients) then
|
||||
local position_encodings = {} ---@type table<integer, table<string, integer[]>>
|
||||
for _, client in pairs(clients) do
|
||||
for bufnr in pairs(client.attached_buffers) do
|
||||
if not position_encodings[bufnr] then
|
||||
position_encodings[bufnr] = {}
|
||||
end
|
||||
if not position_encodings[bufnr][client.offset_encoding] then
|
||||
position_encodings[bufnr][client.offset_encoding] = {}
|
||||
end
|
||||
table.insert(position_encodings[bufnr][client.offset_encoding], client.id)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if any buffers are attached to multiple clients with different position encodings
|
||||
local buffers = {} ---@type integer[]
|
||||
for bufnr, encodings in pairs(position_encodings) do
|
||||
local list = {} ---@type string[]
|
||||
for k in pairs(encodings) do
|
||||
list[#list + 1] = k
|
||||
end
|
||||
|
||||
if #list > 1 then
|
||||
buffers[#buffers + 1] = bufnr
|
||||
end
|
||||
end
|
||||
|
||||
if #buffers > 0 then
|
||||
local lines =
|
||||
{ 'Found buffers attached to multiple clients with different position encodings.' }
|
||||
for _, bufnr in ipairs(buffers) do
|
||||
local encodings = position_encodings[bufnr]
|
||||
local parts = {}
|
||||
for encoding, client_ids in pairs(encodings) do
|
||||
table.insert(
|
||||
parts,
|
||||
string.format('%s (client id(s): %s)', encoding:upper(), table.concat(client_ids, ', '))
|
||||
)
|
||||
end
|
||||
table.insert(lines, string.format('- Buffer %d: %s', bufnr, table.concat(parts, ', ')))
|
||||
end
|
||||
report_warn(
|
||||
table.concat(lines, '\n'),
|
||||
'Use the positionEncodings client capability to ensure all clients use the same position encoding'
|
||||
)
|
||||
else
|
||||
report_info('No buffers contain mixed position encodings')
|
||||
end
|
||||
else
|
||||
report_info('No active clients')
|
||||
end
|
||||
end
|
||||
|
||||
--- Performs a healthcheck for LSP
|
||||
function M.check()
|
||||
check_log()
|
||||
check_active_clients()
|
||||
check_watcher()
|
||||
check_position_encodings()
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -77,12 +77,7 @@ function M.on_inlayhint(err, result, ctx, _)
|
||||
local col = position.character
|
||||
if col > 0 then
|
||||
local line = lines[position.line + 1] or ''
|
||||
local ok, convert_result
|
||||
ok, convert_result = pcall(util._str_byteindex_enc, line, col, client.offset_encoding)
|
||||
if ok then
|
||||
return convert_result
|
||||
end
|
||||
return math.min(#line, col)
|
||||
return util._str_byteindex_enc(line, col, client.offset_encoding)
|
||||
end
|
||||
return col
|
||||
end
|
||||
@ -336,6 +331,8 @@ api.nvim_set_decoration_provider(namespace, {
|
||||
for lnum = topline, botline do
|
||||
if bufstate.applied[lnum] ~= bufstate.version then
|
||||
api.nvim_buf_clear_namespace(bufnr, namespace, lnum, lnum + 1)
|
||||
|
||||
local hint_virtual_texts = {} --- @type table<integer, [string, string?][]>
|
||||
for _, lnum_hints in pairs(client_hints) do
|
||||
local hints = lnum_hints[lnum] or {}
|
||||
for _, hint in pairs(hints) do
|
||||
@ -348,7 +345,7 @@ api.nvim_set_decoration_provider(namespace, {
|
||||
text = text .. part.value
|
||||
end
|
||||
end
|
||||
local vt = {} --- @type {[1]: string, [2]: string?}[]
|
||||
local vt = hint_virtual_texts[hint.position.character] or {}
|
||||
if hint.paddingLeft then
|
||||
vt[#vt + 1] = { ' ' }
|
||||
end
|
||||
@ -356,13 +353,18 @@ api.nvim_set_decoration_provider(namespace, {
|
||||
if hint.paddingRight then
|
||||
vt[#vt + 1] = { ' ' }
|
||||
end
|
||||
api.nvim_buf_set_extmark(bufnr, namespace, lnum, hint.position.character, {
|
||||
virt_text_pos = 'inline',
|
||||
ephemeral = false,
|
||||
virt_text = vt,
|
||||
})
|
||||
hint_virtual_texts[hint.position.character] = vt
|
||||
end
|
||||
end
|
||||
|
||||
for pos, vt in pairs(hint_virtual_texts) do
|
||||
api.nvim_buf_set_extmark(bufnr, namespace, lnum, pos, {
|
||||
virt_text_pos = 'inline',
|
||||
ephemeral = false,
|
||||
virt_text = vt,
|
||||
})
|
||||
end
|
||||
|
||||
bufstate.applied[lnum] = bufstate.version
|
||||
end
|
||||
end
|
||||
@ -370,7 +372,7 @@ api.nvim_set_decoration_provider(namespace, {
|
||||
})
|
||||
|
||||
--- Query whether inlay hint is enabled in the {filter}ed scope
|
||||
--- @param filter vim.lsp.inlay_hint.enable.Filter
|
||||
--- @param filter? vim.lsp.inlay_hint.enable.Filter
|
||||
--- @return boolean
|
||||
--- @since 12
|
||||
function M.is_enabled(filter)
|
||||
|
@ -166,6 +166,7 @@ local constants = {
|
||||
-- Defined by the protocol.
|
||||
RequestCancelled = -32800,
|
||||
ContentModified = -32801,
|
||||
ServerCancelled = -32802,
|
||||
},
|
||||
|
||||
-- Describes the content type that a client supports in various
|
||||
|
@ -3,7 +3,7 @@ local log = require('vim.lsp.log')
|
||||
local protocol = require('vim.lsp.protocol')
|
||||
local validate, schedule, schedule_wrap = vim.validate, vim.schedule, vim.schedule_wrap
|
||||
|
||||
local is_win = uv.os_uname().version:find('Windows')
|
||||
local is_win = vim.fn.has('win32') == 1
|
||||
|
||||
--- Checks whether a given path exists and is a directory.
|
||||
---@param filename string path to check
|
||||
|
@ -140,12 +140,7 @@ local function tokens_to_ranges(data, bufnr, client, request)
|
||||
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)
|
||||
return util._str_byteindex_enc(buf_line, col, client.offset_encoding)
|
||||
end
|
||||
return col
|
||||
end
|
||||
@ -197,12 +192,6 @@ function STHighlighter.new(bufnr)
|
||||
highlighter:send_request()
|
||||
end
|
||||
end,
|
||||
on_detach = function(_, buf)
|
||||
local highlighter = STHighlighter.active[buf]
|
||||
if highlighter then
|
||||
highlighter:destroy()
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
api.nvim_create_autocmd({ 'BufWinEnter', 'InsertLeave' }, {
|
||||
|
@ -120,6 +120,7 @@ end
|
||||
---@param encoding string|nil utf-8|utf-16|utf-32|nil defaults to utf-16
|
||||
---@return integer `encoding` index of `index` in `line`
|
||||
function M._str_utfindex_enc(line, index, encoding)
|
||||
local len32, len16 = vim.str_utfindex(line)
|
||||
if not encoding then
|
||||
encoding = 'utf-16'
|
||||
end
|
||||
@ -130,9 +131,15 @@ function M._str_utfindex_enc(line, index, encoding)
|
||||
return #line
|
||||
end
|
||||
elseif encoding == 'utf-16' then
|
||||
if not index or index > len16 then
|
||||
return len16
|
||||
end
|
||||
local _, col16 = vim.str_utfindex(line, index)
|
||||
return col16
|
||||
elseif encoding == 'utf-32' then
|
||||
if not index or index > len32 then
|
||||
return len32
|
||||
end
|
||||
local col32, _ = vim.str_utfindex(line, index)
|
||||
return col32
|
||||
else
|
||||
@ -148,27 +155,29 @@ end
|
||||
---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16
|
||||
---@return integer byte (utf-8) index of `encoding` index `index` in `line`
|
||||
function M._str_byteindex_enc(line, index, encoding)
|
||||
-- LSP spec: if character > line length, default to the line length.
|
||||
-- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position
|
||||
local len8 = #line
|
||||
if not encoding then
|
||||
encoding = 'utf-16'
|
||||
end
|
||||
if encoding == 'utf-8' then
|
||||
if index then
|
||||
if index and index <= len8 then
|
||||
return index
|
||||
else
|
||||
return #line
|
||||
return len8
|
||||
end
|
||||
elseif encoding == 'utf-16' then
|
||||
return vim.str_byteindex(line, index, true)
|
||||
end
|
||||
local len32, len16 = vim.str_utfindex(line)
|
||||
if encoding == 'utf-16' then
|
||||
return index <= len16 and vim.str_byteindex(line, index, true) or len8
|
||||
elseif encoding == 'utf-32' then
|
||||
return vim.str_byteindex(line, index)
|
||||
return index <= len32 and vim.str_byteindex(line, index) or len8
|
||||
else
|
||||
error('Invalid encoding: ' .. vim.inspect(encoding))
|
||||
end
|
||||
end
|
||||
|
||||
local _str_utfindex_enc = M._str_utfindex_enc
|
||||
local _str_byteindex_enc = M._str_byteindex_enc
|
||||
|
||||
--- Replaces text in a range with new text.
|
||||
---
|
||||
--- CAUTION: Changes in-place!
|
||||
@ -333,12 +342,7 @@ local function get_line_byte_from_position(bufnr, position, offset_encoding)
|
||||
-- character
|
||||
if col > 0 then
|
||||
local line = get_line(bufnr, position.line) or ''
|
||||
local ok, result
|
||||
ok, result = pcall(_str_byteindex_enc, line, col, offset_encoding)
|
||||
if ok then
|
||||
return result
|
||||
end
|
||||
return math.min(#line, col)
|
||||
return M._str_byteindex_enc(line, col, offset_encoding or 'utf-16')
|
||||
end
|
||||
return col
|
||||
end
|
||||
@ -495,14 +499,15 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
|
||||
e.end_col = last_line_len
|
||||
has_eol_text_edit = true
|
||||
else
|
||||
-- If the replacement is over the end of a line (i.e. e.end_col is out of bounds and the
|
||||
-- If the replacement is over the end of a line (i.e. e.end_col is equal to the line length and the
|
||||
-- replacement text ends with a newline We can likely assume that the replacement is assumed
|
||||
-- to be meant to replace the newline with another newline and we need to make sure this
|
||||
-- doesn't add an extra empty line. E.g. when the last line to be replaced contains a '\r'
|
||||
-- in the file some servers (clangd on windows) will include that character in the line
|
||||
-- while nvim_buf_set_text doesn't count it as part of the line.
|
||||
if
|
||||
e.end_col > last_line_len
|
||||
e.end_col >= last_line_len
|
||||
and text_edit.range['end'].character > e.end_col
|
||||
and #text_edit.newText > 0
|
||||
and string.sub(text_edit.newText, -1) == '\n'
|
||||
then
|
||||
@ -1621,7 +1626,7 @@ function M._make_floating_popup_size(contents, opts)
|
||||
if vim.tbl_isempty(line_widths) then
|
||||
for _, line in ipairs(contents) do
|
||||
local line_width = vim.fn.strdisplaywidth(line:gsub('%z', '\n'))
|
||||
height = height + math.ceil(line_width / wrap_at)
|
||||
height = height + math.max(1, math.ceil(line_width / wrap_at))
|
||||
end
|
||||
else
|
||||
for i = 1, #contents do
|
||||
@ -2038,7 +2043,7 @@ local function make_position_param(window, offset_encoding)
|
||||
return { line = 0, character = 0 }
|
||||
end
|
||||
|
||||
col = _str_utfindex_enc(line, col, offset_encoding)
|
||||
col = M._str_utfindex_enc(line, col, offset_encoding)
|
||||
|
||||
return { line = row, character = col }
|
||||
end
|
||||
@ -2219,11 +2224,7 @@ function M.character_offset(buf, row, col, offset_encoding)
|
||||
)
|
||||
offset_encoding = vim.lsp.get_clients({ bufnr = buf })[1].offset_encoding
|
||||
end
|
||||
-- If the col is past the EOL, use the line length.
|
||||
if col > #line then
|
||||
return _str_utfindex_enc(line, nil, offset_encoding)
|
||||
end
|
||||
return _str_utfindex_enc(line, col, offset_encoding)
|
||||
return M._str_utfindex_enc(line, col, offset_encoding)
|
||||
end
|
||||
|
||||
--- Helper function to return nested values in language server settings
|
||||
@ -2305,6 +2306,11 @@ function M._refresh(method, opts)
|
||||
local first = vim.fn.line('w0', window)
|
||||
local last = vim.fn.line('w$', window)
|
||||
for _, client in ipairs(clients) do
|
||||
for rid, req in pairs(client.requests) do
|
||||
if req.method == method and req.type == 'pending' and req.bufnr == bufnr then
|
||||
client.cancel_request(rid)
|
||||
end
|
||||
end
|
||||
client.request(method, {
|
||||
textDocument = textDocument,
|
||||
range = make_line_range_params(bufnr, first - 1, last - 1, client.offset_encoding),
|
||||
|
@ -315,7 +315,7 @@ local function select_tabstop(tabstop)
|
||||
move_cursor_to(range[1] + 1, range[2] + 1)
|
||||
feedkeys('v')
|
||||
move_cursor_to(range[3] + 1, range[4])
|
||||
feedkeys('o<c-g>')
|
||||
feedkeys('o<c-g><c-r>_')
|
||||
end
|
||||
end
|
||||
|
||||
@ -395,6 +395,15 @@ local function setup_autocmds(bufnr)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd('BufLeave', {
|
||||
group = snippet_group,
|
||||
desc = 'Stop the snippet session when leaving the buffer',
|
||||
buffer = bufnr,
|
||||
callback = function()
|
||||
M.stop()
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
--- Expands the given snippet text.
|
||||
@ -444,7 +453,7 @@ function M.expand(input)
|
||||
local snippet_lines = text_to_lines(snippet_text)
|
||||
-- Get the base indentation based on the current line and the last line of the snippet.
|
||||
if #snippet_lines > 0 then
|
||||
base_indent = base_indent .. (snippet_lines[#snippet_lines]:match('(^%s*)%S') or '') --- @type string
|
||||
base_indent = base_indent .. (snippet_lines[#snippet_lines]:match('(^%s+)%S') or '') --- @type string
|
||||
end
|
||||
|
||||
local shiftwidth = vim.fn.shiftwidth()
|
||||
|
@ -18,15 +18,19 @@ end
|
||||
--- Hex decode a string.
|
||||
---
|
||||
--- @param enc string String to decode
|
||||
--- @return string : Decoded string
|
||||
--- @return string? : Decoded string
|
||||
--- @return string? : Error message, if any
|
||||
function M.hexdecode(enc)
|
||||
assert(#enc % 2 == 0, 'string must have an even number of hex characters')
|
||||
if #enc % 2 ~= 0 then
|
||||
return nil, 'string must have an even number of hex characters'
|
||||
end
|
||||
|
||||
local str = {} ---@type string[]
|
||||
for i = 1, #enc, 2 do
|
||||
local n = assert(tonumber(enc:sub(i, i + 1), 16))
|
||||
str[#str + 1] = string.char(n)
|
||||
end
|
||||
return table.concat(str)
|
||||
return table.concat(str), nil
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -87,7 +87,7 @@ end
|
||||
---@param srow integer
|
||||
---@param erow integer 0-indexed, exclusive
|
||||
function FoldInfo:add_range(srow, erow)
|
||||
list_insert(self.levels, srow + 1, erow, '=')
|
||||
list_insert(self.levels, srow + 1, erow, -1)
|
||||
list_insert(self.levels0, srow + 1, erow, -1)
|
||||
end
|
||||
|
||||
@ -268,6 +268,15 @@ end
|
||||
|
||||
---@package
|
||||
function FoldInfo:do_foldupdate(bufnr)
|
||||
-- InsertLeave is not executed when <C-C> is used for exiting the insert mode, leaving
|
||||
-- do_foldupdate untouched. If another execution of foldupdate consumes foldupdate_range, the
|
||||
-- InsertLeave do_foldupdate gets nil foldupdate_range. In that case, skip the update. This is
|
||||
-- correct because the update that consumed the range must have incorporated the range that
|
||||
-- InsertLeave meant to update.
|
||||
if not self.foldupdate_range then
|
||||
return
|
||||
end
|
||||
|
||||
local srow, erow = self.foldupdate_range[1], self.foldupdate_range[2]
|
||||
self.foldupdate_range = nil
|
||||
for _, win in ipairs(vim.fn.win_findbuf(bufnr)) do
|
||||
@ -421,9 +430,15 @@ api.nvim_create_autocmd('OptionSet', {
|
||||
pattern = { 'foldminlines', 'foldnestmax' },
|
||||
desc = 'Refresh treesitter folds',
|
||||
callback = function()
|
||||
for bufnr, _ in pairs(foldinfos) do
|
||||
local buf = api.nvim_get_current_buf()
|
||||
local bufs = vim.v.option_type == 'global' and vim.tbl_keys(foldinfos)
|
||||
or foldinfos[buf] and { buf }
|
||||
or {}
|
||||
for _, bufnr in ipairs(bufs) do
|
||||
foldinfos[bufnr] = FoldInfo.new()
|
||||
compute_folds_levels(bufnr, foldinfos[bufnr])
|
||||
api.nvim_buf_call(bufnr, function()
|
||||
compute_folds_levels(bufnr, foldinfos[bufnr])
|
||||
end)
|
||||
foldinfos[bufnr]:foldupdate(bufnr, 0, api.nvim_buf_line_count(bufnr))
|
||||
end
|
||||
end,
|
||||
|
@ -40,7 +40,8 @@ end
|
||||
local function guess_query_lang(buf)
|
||||
local filename = api.nvim_buf_get_name(buf)
|
||||
if filename ~= '' then
|
||||
return vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t')
|
||||
local resolved_filename = vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t')
|
||||
return resolved_filename and vim.treesitter.language.get_lang(resolved_filename) or nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -64,7 +65,7 @@ local function normalize_opts(buf, opts)
|
||||
end
|
||||
|
||||
local lint_query = [[;; query
|
||||
(program [(named_node) (list) (grouping)] @toplevel)
|
||||
(program [(named_node) (anonymous_node) (list) (grouping)] @toplevel)
|
||||
(named_node
|
||||
name: _ @node.named)
|
||||
(anonymous_node
|
||||
@ -170,17 +171,17 @@ function M.lint(buf, opts)
|
||||
|
||||
--- @type (table|nil)
|
||||
local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang)
|
||||
local lang_context = {
|
||||
lang = lang,
|
||||
parser_info = parser_info,
|
||||
is_first_lang = i == 1,
|
||||
}
|
||||
|
||||
local parser = vim.treesitter.get_parser(buf)
|
||||
parser:parse()
|
||||
parser:for_each_tree(function(tree, ltree)
|
||||
if ltree:lang() == 'query' then
|
||||
for _, match, _ in query:iter_matches(tree:root(), buf, 0, -1, { all = true }) do
|
||||
local lang_context = {
|
||||
lang = lang,
|
||||
parser_info = parser_info,
|
||||
is_first_lang = i == 1,
|
||||
}
|
||||
lint_match(buf, match, query, lang_context, diagnostics)
|
||||
end
|
||||
end
|
||||
@ -240,7 +241,7 @@ function M.omnifunc(findstart, base)
|
||||
end
|
||||
end
|
||||
for _, s in pairs(parser_info.symbols) do
|
||||
local text = s[2] and s[1] or '"' .. s[1]:gsub([[\]], [[\\]]) .. '"' ---@type string
|
||||
local text = s[2] and s[1] or string.format('%q', s[1]):gsub('\n', 'n') ---@type string
|
||||
if text:find(base, 1, true) then
|
||||
table.insert(items, text)
|
||||
end
|
||||
|
@ -154,7 +154,8 @@ end
|
||||
|
||||
---@param w integer
|
||||
---@param b integer
|
||||
local function set_dev_properties(w, b)
|
||||
---@param opts nil|{ indent?: integer }
|
||||
local function set_dev_options(w, b, opts)
|
||||
vim.wo[w].scrolloff = 5
|
||||
vim.wo[w].wrap = false
|
||||
vim.wo[w].foldmethod = 'expr'
|
||||
@ -165,6 +166,12 @@ local function set_dev_properties(w, b)
|
||||
vim.bo[b].buftype = 'nofile'
|
||||
vim.bo[b].bufhidden = 'wipe'
|
||||
vim.bo[b].filetype = 'query'
|
||||
vim.bo[b].swapfile = false
|
||||
|
||||
opts = opts or {}
|
||||
if opts.indent then
|
||||
vim.bo[b].shiftwidth = opts.indent
|
||||
end
|
||||
end
|
||||
|
||||
--- Updates the cursor position in the inspector to match the node under the cursor.
|
||||
@ -220,14 +227,13 @@ function TSTreeView:draw(bufnr)
|
||||
|
||||
local text ---@type string
|
||||
if item.node:named() then
|
||||
if item.field then
|
||||
text = string.format('%s: (%s', item.field, item.node:type())
|
||||
else
|
||||
text = string.format('(%s', item.node:type())
|
||||
end
|
||||
text = string.format('(%s', item.node:type())
|
||||
else
|
||||
text = string.format('%q', item.node:type()):gsub('\n', 'n')
|
||||
end
|
||||
if item.field then
|
||||
text = string.format('%s: %s', item.field, text)
|
||||
end
|
||||
|
||||
local next = self:get(i + 1)
|
||||
if not next or next.depth <= item.depth then
|
||||
@ -350,7 +356,7 @@ function M.inspect_tree(opts)
|
||||
vim.b[buf].dev_inspect = w
|
||||
vim.b[b].dev_base = win -- base window handle
|
||||
vim.b[b].disable_query_linter = true
|
||||
set_dev_properties(w, b)
|
||||
set_dev_options(w, b, { indent = treeview.opts.indent })
|
||||
|
||||
local title --- @type string?
|
||||
local opts_title = opts.title
|
||||
@ -587,7 +593,7 @@ function M.edit_query(lang)
|
||||
|
||||
vim.b[buf].dev_edit = query_win
|
||||
vim.bo[query_buf].omnifunc = 'v:lua.vim.treesitter.query.omnifunc'
|
||||
set_dev_properties(query_win, query_buf)
|
||||
set_dev_options(query_win, query_buf)
|
||||
|
||||
-- Note that omnifunc guesses the language based on the containing folder,
|
||||
-- so we add the parser's language to the buffer's name so that omnifunc
|
||||
|
@ -139,8 +139,11 @@ function TSHighlighter.new(tree, opts)
|
||||
-- but use synload.vim rather than syntax.vim to not enable
|
||||
-- syntax FileType autocmds. Later on we should integrate with the
|
||||
-- `:syntax` and `set syntax=...` machinery properly.
|
||||
-- Still need to ensure that syntaxset augroup exists, so that calling :destroy()
|
||||
-- immediately afterwards will not error.
|
||||
if vim.g.syntax_on ~= 1 then
|
||||
vim.cmd.runtime({ 'syntax/synload.vim', bang = true })
|
||||
vim.api.nvim_create_augroup('syntaxset', { clear = false })
|
||||
end
|
||||
|
||||
api.nvim_buf_call(self.bufnr, function()
|
||||
@ -377,11 +380,15 @@ function TSHighlighter._on_spell_nav(_, _, buf, srow, _, erow, _)
|
||||
return
|
||||
end
|
||||
|
||||
-- Do not affect potentially populated highlight state. Here we just want a temporary
|
||||
-- empty state so the C code can detect whether the region should be spell checked.
|
||||
local highlight_states = self._highlight_states
|
||||
self:prepare_highlight_states(srow, erow)
|
||||
|
||||
for row = srow, erow do
|
||||
on_line_impl(self, buf, row, true)
|
||||
end
|
||||
self._highlight_states = highlight_states
|
||||
end
|
||||
|
||||
---@private
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user