mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
Compare commits
266 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b2684d9f66 | ||
![]() |
7da0c46e1b | ||
![]() |
91ef8606f2 | ||
![]() |
89959ab9dc | ||
![]() |
adf31505d8 | ||
![]() |
f9f0345eba | ||
![]() |
6f8efea940 | ||
![]() |
388b559848 | ||
![]() |
c97ad3cb41 | ||
![]() |
2ddb5d21bb | ||
![]() |
6889f9168b | ||
![]() |
2d3a4154c5 | ||
![]() |
87ba1d7465 | ||
![]() |
0ab089add4 | ||
![]() |
2d13ae0dd4 | ||
![]() |
730a5e0599 | ||
![]() |
85c9014c09 | ||
![]() |
282f9fb816 | ||
![]() |
d1214da08f | ||
![]() |
f0f163b267 | ||
![]() |
2df746e4e8 | ||
![]() |
b9dbdfef0e | ||
![]() |
0f81af53b0 | ||
![]() |
a80bdf0d9b | ||
![]() |
37fb09c162 | ||
![]() |
e732cbe36c | ||
![]() |
2d3517012a | ||
![]() |
41ceefe804 | ||
![]() |
7b2119dbd9 | ||
![]() |
ef68eae09a | ||
![]() |
43804477ca | ||
![]() |
bfcf541a9e | ||
![]() |
28531d18f0 | ||
![]() |
d5cbc99358 | ||
![]() |
db3b856779 | ||
![]() |
e6eb910496 | ||
![]() |
7286e514f2 | ||
![]() |
ae05e0399b | ||
![]() |
4621527f59 | ||
![]() |
638bc951b2 | ||
![]() |
0613faf596 | ||
![]() |
203d4f916d | ||
![]() |
68d204462c | ||
![]() |
70b4e7948f | ||
![]() |
ee06d0e64d | ||
![]() |
1976ca68b5 | ||
![]() |
4303337c77 | ||
![]() |
ecf5164d2d | ||
![]() |
6396bfb29f | ||
![]() |
ea8db9003b | ||
![]() |
ff8acfffd2 | ||
![]() |
9ffa94b07b | ||
![]() |
1077374380 | ||
![]() |
3d5be364bc | ||
![]() |
ce292026ea | ||
![]() |
742ea00742 | ||
![]() |
a34b8e42df | ||
![]() |
77eb278adf | ||
![]() |
d0a24ea03e | ||
![]() |
ec84c8df0e | ||
![]() |
c4a760c734 | ||
![]() |
902c946bcd | ||
![]() |
0f1cada0f7 | ||
![]() |
c5bc0289ed | ||
![]() |
d28ad6e03f | ||
![]() |
b0ced63e43 | ||
![]() |
0eec4a8ecc | ||
![]() |
36c6f488e4 | ||
![]() |
5d0766ddce | ||
![]() |
718b3ffe74 | ||
![]() |
7184230e94 | ||
![]() |
d9b9514e8e | ||
![]() |
dfeec113be | ||
![]() |
8183eb32e1 | ||
![]() |
8d3b7b57c8 | ||
![]() |
c0201909c7 | ||
![]() |
a03057560a | ||
![]() |
95e5c9f33e | ||
![]() |
07d9197840 | ||
![]() |
c13eba5254 | ||
![]() |
d32a4dd4b0 | ||
![]() |
7ef602d470 | ||
![]() |
9d8c5119e2 | ||
![]() |
f7b1b0595d | ||
![]() |
25a869a097 | ||
![]() |
243c15ea83 | ||
![]() |
33cec55a26 | ||
![]() |
e0ddf93bb0 | ||
![]() |
aa6136f956 | ||
![]() |
222b3d5021 | ||
![]() |
0d66963089 | ||
![]() |
f2c4305114 | ||
![]() |
d519b77d2b | ||
![]() |
d9c10ea753 | ||
![]() |
1eb33f7d00 | ||
![]() |
92dc936ca7 | ||
![]() |
68677eb477 | ||
![]() |
f4a79230c8 | ||
![]() |
a73904168a | ||
![]() |
58460e2d52 | ||
![]() |
3a0d37681f | ||
![]() |
4cb2b19197 | ||
![]() |
d1ca551983 | ||
![]() |
5e0ef6afc7 | ||
![]() |
cefc91a82e | ||
![]() |
334d8f506f | ||
![]() |
ff83c712cf | ||
![]() |
b07bffdc47 | ||
![]() |
b868257ef9 | ||
![]() |
e304677993 | ||
![]() |
4e5af2f5a6 | ||
![]() |
917f496f75 | ||
![]() |
a242902430 | ||
![]() |
12ae7aa846 | ||
![]() |
27abf5c81b | ||
![]() |
d50f71d2f1 | ||
![]() |
f623fad9c4 | ||
![]() |
3e83a33108 | ||
![]() |
0c2bf55e90 | ||
![]() |
6b140ae899 | ||
![]() |
1921dda92e | ||
![]() |
30fa1c5f8c | ||
![]() |
6417ba0c2f | ||
![]() |
3c102303f5 | ||
![]() |
034d3c8f6c | ||
![]() |
9965cfb84c | ||
![]() |
bdd8498ed7 | ||
![]() |
8daffd0cbb | ||
![]() |
fd8e0ae62d | ||
![]() |
a56dcbbad7 | ||
![]() |
6a87b57c06 | ||
![]() |
5c6ee251a6 | ||
![]() |
0db89468d7 | ||
![]() |
dc87a0d80a | ||
![]() |
c753e70abb | ||
![]() |
0ed06d7271 | ||
![]() |
e512c9589e | ||
![]() |
47686a1454 | ||
![]() |
3b3cf1d7ef | ||
![]() |
472d41b5b6 | ||
![]() |
216c56b7e0 | ||
![]() |
968947b3c3 | ||
![]() |
9b3426691c | ||
![]() |
4e43264cd3 | ||
![]() |
3a4d3934c4 | ||
![]() |
2b2a3449f7 | ||
![]() |
6b69b3217b | ||
![]() |
cf73f21c07 | ||
![]() |
e5e69f758d | ||
![]() |
901eeeb2e6 | ||
![]() |
6563c6bde7 | ||
![]() |
465c181581 | ||
![]() |
710d561f88 | ||
![]() |
81233a41d7 | ||
![]() |
c4b9bdbdf4 | ||
![]() |
560c6ca947 | ||
![]() |
4b6caa913c | ||
![]() |
0fbc78caa1 | ||
![]() |
533ec6d492 | ||
![]() |
9dfb429e93 | ||
![]() |
051e14d347 | ||
![]() |
714622fb45 | ||
![]() |
4296511087 | ||
![]() |
f9c7a69cec | ||
![]() |
fa292e6f61 | ||
![]() |
bc66a5ff6f | ||
![]() |
f25f6c8d13 | ||
![]() |
ad7211ac8f | ||
![]() |
95ee908c40 | ||
![]() |
d68d212ad4 | ||
![]() |
3273c595c0 | ||
![]() |
3db39ed21f | ||
![]() |
f184c562c5 | ||
![]() |
32842b0ee3 | ||
![]() |
4f0e828190 | ||
![]() |
a9a3981669 | ||
![]() |
478f5d0070 | ||
![]() |
95f96a3d1b | ||
![]() |
9909580df2 | ||
![]() |
66953b16a2 | ||
![]() |
448c2cec9d | ||
![]() |
c1d3777db2 | ||
![]() |
155529b91a | ||
![]() |
c633250cc0 | ||
![]() |
0c315feddf | ||
![]() |
646a8f663e | ||
![]() |
b9c9b15ad7 | ||
![]() |
fb71d631a5 | ||
![]() |
3b0c88a537 | ||
![]() |
1a6ddeee41 | ||
![]() |
4205fdee1d | ||
![]() |
248528c907 | ||
![]() |
b7de104d86 | ||
![]() |
cdd3f2a2e6 | ||
![]() |
a97713485d | ||
![]() |
12298be0fe | ||
![]() |
2435d72283 | ||
![]() |
e342b9a25a | ||
![]() |
4422b9bbd0 | ||
![]() |
dcd5e4574a | ||
![]() |
b694131c3b | ||
![]() |
4d87229789 | ||
![]() |
e4007551c4 | ||
![]() |
526444c4ff | ||
![]() |
8aa49a8e9b | ||
![]() |
2b14447803 | ||
![]() |
7384983721 | ||
![]() |
b8e5fd51fd | ||
![]() |
9da90af0f7 | ||
![]() |
b5158e8e92 | ||
![]() |
837faf7065 | ||
![]() |
c4a19bff4e | ||
![]() |
a92155b86b | ||
![]() |
6e51d39696 | ||
![]() |
4c1121bd33 | ||
![]() |
c158d41cec | ||
![]() |
2182272139 | ||
![]() |
29011e4d45 | ||
![]() |
91481ae7d5 | ||
![]() |
3df9db58dc | ||
![]() |
e3506ede27 | ||
![]() |
02bf23b4bf | ||
![]() |
cbf4906c11 | ||
![]() |
4cc97cf009 | ||
![]() |
c6ef13dc45 | ||
![]() |
1a2d0484ac | ||
![]() |
5829b5de0a | ||
![]() |
dd547ef1ea | ||
![]() |
91d11c8bc1 | ||
![]() |
1daea6e1fd | ||
![]() |
279a0e78c9 | ||
![]() |
5fc6bd6454 | ||
![]() |
2b2a90051e | ||
![]() |
1e8e74dbff | ||
![]() |
a4b6705e87 | ||
![]() |
f68e0fed26 | ||
![]() |
09fd22d5d7 | ||
![]() |
326eacef93 | ||
![]() |
02123bac0d | ||
![]() |
8d9b4d8c14 | ||
![]() |
55be20316a | ||
![]() |
12da443930 | ||
![]() |
837c9d0409 | ||
![]() |
70f3e15298 | ||
![]() |
7e884b78bf | ||
![]() |
89e0ea1788 | ||
![]() |
9056c01a95 | ||
![]() |
d2dd403693 | ||
![]() |
2084cda6f9 | ||
![]() |
7efb3ba6f7 | ||
![]() |
649bce6e73 | ||
![]() |
fcee5df0fc | ||
![]() |
2a04161a35 | ||
![]() |
adfd4b9f4f | ||
![]() |
056dbf3ea7 | ||
![]() |
c57a36cd59 | ||
![]() |
06df3e0c0d | ||
![]() |
a9afa6b152 | ||
![]() |
bbf912d72f | ||
![]() |
53def2a877 | ||
![]() |
c61e8c6e70 | ||
![]() |
6514e2c7ba | ||
![]() |
06c2886569 | ||
![]() |
2cd735d159 | ||
![]() |
ccb078bbb0 | ||
![]() |
5e4365b83d |
@@ -18,7 +18,6 @@ Checks: >
|
|||||||
-bugprone-not-null-terminated-result,
|
-bugprone-not-null-terminated-result,
|
||||||
-bugprone-suspicious-memory-comparison,
|
-bugprone-suspicious-memory-comparison,
|
||||||
-bugprone-switch-missing-default-case,
|
-bugprone-switch-missing-default-case,
|
||||||
-bugprone-tagged-union-member-count,
|
|
||||||
-cert-env33-c,
|
-cert-env33-c,
|
||||||
-cert-err33-c,
|
-cert-err33-c,
|
||||||
-cert-err34-c,
|
-cert-err34-c,
|
||||||
@@ -64,7 +63,6 @@ Checks: >
|
|||||||
|
|
||||||
Aliases. These are just duplicates of other warnings and should always be ignored,
|
Aliases. These are just duplicates of other warnings and should always be ignored,
|
||||||
-bugprone-narrowing-conversions,
|
-bugprone-narrowing-conversions,
|
||||||
-cert-arr39-c,
|
|
||||||
-cert-dcl37-c,
|
-cert-dcl37-c,
|
||||||
-cert-dcl51-cpp,
|
-cert-dcl51-cpp,
|
||||||
-cert-exp42-c,
|
-cert-exp42-c,
|
||||||
|
25
.emmyrc.json
25
.emmyrc.json
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
|
|
||||||
"format": {
|
|
||||||
"externalTool": {
|
|
||||||
"program": "stylua",
|
|
||||||
"args": [
|
|
||||||
"-",
|
|
||||||
"--stdin-filepath",
|
|
||||||
"${file}"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"diagnostics": {
|
|
||||||
"disable": [
|
|
||||||
"unnecessary-if"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"codeAction": {
|
|
||||||
"insertSpace": true
|
|
||||||
},
|
|
||||||
"strict": {
|
|
||||||
"typeCall": true,
|
|
||||||
"arrayIndex": true
|
|
||||||
}
|
|
||||||
}
|
|
0
.gitattributes
vendored
Normal file → Executable file
0
.gitattributes
vendored
Normal file → Executable file
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
@@ -1,5 +0,0 @@
|
|||||||
<!--
|
|
||||||
Thank you for contributing to Neovim!
|
|
||||||
If this is your first time, check out https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#pull-requests-prs
|
|
||||||
for our PR guidelines.
|
|
||||||
-->
|
|
20
.github/scripts/env.ps1
vendored
20
.github/scripts/env.ps1
vendored
@@ -1,17 +1,9 @@
|
|||||||
# This script enables Developer Command Prompt
|
# This script enables Developer Command Prompt
|
||||||
# See https://github.com/microsoft/vswhere/wiki/Start-Developer-Command-Prompt#using-powershell
|
# See https://github.com/microsoft/vswhere/wiki/Start-Developer-Command-Prompt#using-powershell
|
||||||
if ($env:BUILD_ARCH -eq "arm64") {
|
$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||||
$arch = "arm64"
|
if ($installationPath -and (Test-Path "$installationPath\Common7\Tools\vsdevcmd.bat")) {
|
||||||
$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.arm64 -property installationPath
|
& "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=x64 -no_logo && set" | ForEach-Object {
|
||||||
} else {
|
$name, $value = $_ -split '=', 2
|
||||||
$arch = "x64"
|
"$name=$value" >> $env:GITHUB_ENV
|
||||||
$installationPath = vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ($installationPath) {
|
|
||||||
& "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -arch=$arch -no_logo && set" |
|
|
||||||
ForEach-Object {
|
|
||||||
$name, $value = $_ -split '=', 2
|
|
||||||
"$name=$value" >> $env:GITHUB_ENV
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
2
.github/scripts/reviewers_add.js
vendored
2
.github/scripts/reviewers_add.js
vendored
@@ -57,7 +57,6 @@ module.exports = async ({ github, context }) => {
|
|||||||
|
|
||||||
if (labels.includes("lsp")) {
|
if (labels.includes("lsp")) {
|
||||||
reviewers.add("MariaSolOs");
|
reviewers.add("MariaSolOs");
|
||||||
reviewers.add("ribru17");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes("netrw")) {
|
if (labels.includes("netrw")) {
|
||||||
@@ -90,7 +89,6 @@ module.exports = async ({ github, context }) => {
|
|||||||
reviewers.add("clason");
|
reviewers.add("clason");
|
||||||
reviewers.add("lewis6991");
|
reviewers.add("lewis6991");
|
||||||
reviewers.add("wookayin");
|
reviewers.add("wookayin");
|
||||||
reviewers.add("ribru17");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labels.includes("tui")) {
|
if (labels.includes("tui")) {
|
||||||
|
6
.github/workflows/backport.yml
vendored
6
.github/workflows/backport.yml
vendored
@@ -11,9 +11,9 @@ jobs:
|
|||||||
if: github.event.pull_request.merged
|
if: github.event.pull_request.merged
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/create-github-app-token@v2
|
- uses: actions/create-github-app-token@v1
|
||||||
id: app-token
|
id: app-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ vars.BACKPORT_APP }}
|
app-id: ${{ vars.BACKPORT_APP }}
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create failed backport label
|
- name: Create failed backport label
|
||||||
if: ${{ steps.backport.outputs.was_successful == 'false' }}
|
if: ${{ steps.backport.outputs.was_successful == 'false' }}
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.issues.addLabels({
|
github.rest.issues.addLabels({
|
||||||
|
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
|||||||
test: [ubuntu-latest, macos-latest, windows-latest]
|
test: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
runs-on: ${{ matrix.test }}
|
runs-on: ${{ matrix.test }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
- run: |
|
- run: |
|
||||||
cmake -S cmake.deps --preset ci -D ENABLE_WASMTIME=ON
|
cmake -S cmake.deps --preset ci -D ENABLE_WASMTIME=ON
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
CMAKE_URL: 'https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.sh'
|
CMAKE_URL: 'https://cmake.org/files/v3.16/cmake-3.16.0-Linux-x86_64.sh'
|
||||||
CMAKE_VERSION: '3.16.0'
|
CMAKE_VERSION: '3.16.0'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Install minimum required version of cmake
|
- name: Install minimum required version of cmake
|
||||||
@@ -73,7 +73,7 @@ jobs:
|
|||||||
name: Test USE_EXISTING_SRC_DIR=ON builds with no network access
|
name: Test USE_EXISTING_SRC_DIR=ON builds with no network access
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Build bundled dependencies
|
- name: Build bundled dependencies
|
||||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
security-events: write
|
security-events: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
|
2
.github/workflows/coverity.yml
vendored
2
.github/workflows/coverity.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
|||||||
scan:
|
scan:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Download Coverity
|
- name: Download Coverity
|
||||||
|
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Generate docs
|
- name: Generate docs
|
||||||
|
2
.github/workflows/labeler_issue.yml
vendored
2
.github/workflows/labeler_issue.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: check issue title
|
- name: check issue title
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const title = context.payload.issue.title;
|
const title = context.payload.issue.title;
|
||||||
|
6
.github/workflows/labeler_pr.yml
vendored
6
.github/workflows/labeler_pr.yml
vendored
@@ -9,8 +9,8 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/labeler@v6
|
- uses: actions/labeler@v5
|
||||||
with:
|
with:
|
||||||
configuration-path: .github/scripts/labeler_configuration.yml
|
configuration-path: .github/scripts/labeler_configuration.yml
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- if: startsWith(github.base_ref, 'release')
|
- if: startsWith(github.base_ref, 'release')
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.issues.addLabels({
|
github.rest.issues.addLabels({
|
||||||
|
2
.github/workflows/lintcommit.yml
vendored
2
.github/workflows/lintcommit.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
2
.github/workflows/news.yml
vendored
2
.github/workflows/news.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci:skip-news')
|
if: github.event.pull_request.draft == false && !contains(github.event.pull_request.labels.*.name, 'ci:skip-news')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
17
.github/workflows/notes.md
vendored
17
.github/workflows/notes.md
vendored
@@ -2,26 +2,21 @@
|
|||||||
${NVIM_VERSION}
|
${NVIM_VERSION}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Release notes
|
|
||||||
|
|
||||||
- [Changelog](https://github.com/neovim/neovim/commit/${NVIM_COMMIT}) (fixes + features)
|
|
||||||
- [News](./runtime/doc/news.txt) (`:help news` in Nvim)
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
#### Zip
|
#### Zip
|
||||||
|
|
||||||
1. Download **nvim-win64.zip** (or **nvim-win-arm64.zip** for ARM)
|
1. Download **nvim-win64.zip**
|
||||||
2. Extract the zip
|
2. Extract the zip
|
||||||
3. Run `nvim.exe` in your terminal
|
3. Run `nvim.exe` on your CLI of choice
|
||||||
|
|
||||||
#### MSI
|
#### MSI
|
||||||
|
|
||||||
1. Download **nvim-win64.msi** (or **nvim-win-arm64.msi** for ARM)
|
1. Download **nvim-win64.msi**
|
||||||
2. Run the MSI
|
2. Run the MSI
|
||||||
3. Run `nvim.exe` in your terminal
|
3. Run `nvim.exe` on your CLI of choice
|
||||||
|
|
||||||
Note: On Windows "Server" you may need to [install vcruntime140.dll](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
|
Note: On Windows "Server" you may need to [install vcruntime140.dll](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170).
|
||||||
|
|
||||||
@@ -41,7 +36,7 @@ Note: On Windows "Server" you may need to [install vcruntime140.dll](https://lea
|
|||||||
|
|
||||||
### Linux (x86_64)
|
### Linux (x86_64)
|
||||||
|
|
||||||
If your system does not have the required glibc version, try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases).
|
If your system does not have the [required glibc version](https://neovim.io/doc/user/support.html#supported-platforms), try the (unsupported) [builds for older glibc](https://github.com/neovim/neovim-releases).
|
||||||
|
|
||||||
#### AppImage
|
#### AppImage
|
||||||
|
|
||||||
@@ -59,7 +54,7 @@ If your system does not have the required glibc version, try the (unsupported) [
|
|||||||
2. Extract: `tar xzvf nvim-linux-x86_64.tar.gz`
|
2. Extract: `tar xzvf nvim-linux-x86_64.tar.gz`
|
||||||
3. Run `./nvim-linux-x86_64/bin/nvim`
|
3. Run `./nvim-linux-x86_64/bin/nvim`
|
||||||
|
|
||||||
### Linux (arm64)
|
### Linux (arm64) - Untested
|
||||||
|
|
||||||
#### AppImage
|
#### AppImage
|
||||||
|
|
||||||
|
44
.github/workflows/release.yml
vendored
44
.github/workflows/release.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.build.outputs.version }}
|
version: ${{ steps.build.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Perform a full checkout #13471
|
# Perform a full checkout #13471
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -101,7 +101,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: 11.0
|
MACOSX_DEPLOYMENT_TARGET: 11.0
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Perform a full checkout #13471
|
# Perform a full checkout #13471
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -132,44 +132,27 @@ jobs:
|
|||||||
|
|
||||||
windows:
|
windows:
|
||||||
needs: setup
|
needs: setup
|
||||||
strategy:
|
runs-on: windows-2022
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- runner: windows-2022
|
|
||||||
arch: x86_64
|
|
||||||
archive_name: nvim-win64
|
|
||||||
- runner: windows-11-arm
|
|
||||||
arch: arm64
|
|
||||||
archive_name: nvim-win-arm64
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Perform a full checkout #13471
|
# Perform a full checkout #13471
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- run: .github/scripts/env.ps1
|
- run: .github/scripts/env.ps1
|
||||||
env:
|
|
||||||
BUILD_ARCH: ${{ matrix.arch }}
|
|
||||||
- name: Install Wix
|
|
||||||
run: |
|
|
||||||
Invoke-WebRequest -Uri "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip" -OutFile "wix314-binaries.zip"
|
|
||||||
Expand-Archive -Path "wix314-binaries.zip" -DestinationPath "C:/wix"
|
|
||||||
echo "C:\wix" >> $env:GITHUB_PATH
|
|
||||||
- name: Build deps
|
- name: Build deps
|
||||||
run: |
|
run: |
|
||||||
cmake -S cmake.deps -B .deps -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}
|
cmake -S cmake.deps -B .deps -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}
|
||||||
cmake --build .deps
|
cmake --build .deps
|
||||||
- name: Build package
|
- name: build package
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}
|
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=${{ needs.setup.outputs.build_type }}
|
||||||
cmake --build build --target package
|
cmake --build build --target package
|
||||||
- name: Upload artifact
|
- uses: actions/upload-artifact@v4
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
with:
|
||||||
name: nvim-win-${{ matrix.arch }}
|
name: nvim-win64
|
||||||
path: |
|
path: |
|
||||||
build/${{ matrix.archive_name }}.zip
|
build/nvim-win64.msi
|
||||||
build/${{ matrix.archive_name }}.msi
|
build/nvim-win64.zip
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
@@ -183,9 +166,9 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Must perform checkout first, since it deletes the target directory
|
# Must perform checkout first, since it deletes the target directory
|
||||||
# before running, and would therefore delete the downloaded artifacts
|
# before running, and would therefore delete the downloaded artifacts
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/download-artifact@v5
|
- uses: actions/download-artifact@v4
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt-get install -y gettext-base
|
run: sudo apt-get update && sudo apt-get install -y gettext-base
|
||||||
@@ -213,11 +196,10 @@ jobs:
|
|||||||
- name: Publish release
|
- name: Publish release
|
||||||
env:
|
env:
|
||||||
NVIM_VERSION: ${{ needs.linux.outputs.version }}
|
NVIM_VERSION: ${{ needs.linux.outputs.version }}
|
||||||
NVIM_COMMIT: ${{ github.sha }}
|
|
||||||
DEBUG: api
|
DEBUG: api
|
||||||
run: |
|
run: |
|
||||||
envsubst < "$GITHUB_WORKSPACE/.github/workflows/notes.md" > "$RUNNER_TEMP/notes.md"
|
envsubst < "$GITHUB_WORKSPACE/.github/workflows/notes.md" > "$RUNNER_TEMP/notes.md"
|
||||||
if [ "$TAG_NAME" != "nightly" ]; then
|
if [ "$TAG_NAME" != "nightly" ]; then
|
||||||
gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win-x86_64/* nvim-win-arm64/*
|
gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win64/*
|
||||||
fi
|
fi
|
||||||
gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win-x86_64/* nvim-win-arm64/*
|
gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win64/*
|
||||||
|
8
.github/workflows/response.yml
vendored
8
.github/workflows/response.yml
vendored
@@ -13,8 +13,8 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/github-script@v8
|
- uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/close_unresponsive.js')
|
const script = require('./.github/scripts/close_unresponsive.js')
|
||||||
@@ -27,8 +27,8 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/github-script@v8
|
- uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/remove_response_label.js')
|
const script = require('./.github/scripts/remove_response_label.js')
|
||||||
|
4
.github/workflows/reviewers_add.yml
vendored
4
.github/workflows/reviewers_add.yml
vendored
@@ -10,9 +10,9 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- name: 'Request reviewers'
|
- name: 'Request reviewers'
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/reviewers_add.js')
|
const script = require('./.github/scripts/reviewers_add.js')
|
||||||
|
4
.github/workflows/reviewers_remove.yml
vendored
4
.github/workflows/reviewers_remove.yml
vendored
@@ -8,9 +8,9 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- name: 'Remove reviewers'
|
- name: 'Remove reviewers'
|
||||||
uses: actions/github-script@v8
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const script = require('./.github/scripts/reviewers_remove.js')
|
const script = require('./.github/scripts/reviewers_remove.js')
|
||||||
|
42
.github/workflows/test.yml
vendored
42
.github/workflows/test.yml
vendored
@@ -28,17 +28,17 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-24.04
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
env:
|
||||||
CC: clang
|
CC: clang
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Install stylua
|
- name: Install stylua
|
||||||
run: |
|
run: |
|
||||||
wget --directory-prefix="$BIN_DIR" https://github.com/JohnnyMorganz/StyLua/releases/latest/download/stylua-linux-aarch64.zip
|
wget --directory-prefix="$BIN_DIR" https://github.com/JohnnyMorganz/StyLua/releases/latest/download/stylua-linux-x86_64.zip
|
||||||
(cd "$BIN_DIR"; unzip stylua*.zip)
|
(cd "$BIN_DIR"; unzip stylua*.zip)
|
||||||
|
|
||||||
- name: Build third-party deps
|
- name: Build third-party deps
|
||||||
@@ -82,12 +82,12 @@ jobs:
|
|||||||
run: cmake --build build --target lintc-uncrustify
|
run: cmake --build build --target lintc-uncrustify
|
||||||
|
|
||||||
clang-analyzer:
|
clang-analyzer:
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-24.04
|
||||||
timeout-minutes: 20
|
timeout-minutes: 20
|
||||||
env:
|
env:
|
||||||
CC: clang
|
CC: clang
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
- name: Build third-party deps
|
- name: Build third-party deps
|
||||||
run: |
|
run: |
|
||||||
@@ -111,7 +111,7 @@ jobs:
|
|||||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON },
|
{ runner: ubuntu-24.04, os: ubuntu, flavor: 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: tsan, cc: clang, flags: -D ENABLE_TSAN=ON },
|
||||||
{ runner: ubuntu-24.04, os: ubuntu, flavor: release, cc: gcc, flags: -D CMAKE_BUILD_TYPE=Release -D ENABLE_TRANSLATIONS=ON },
|
{ runner: ubuntu-24.04, os: ubuntu, flavor: release, cc: gcc, flags: -D CMAKE_BUILD_TYPE=Release -D ENABLE_TRANSLATIONS=ON },
|
||||||
{ runner: ubuntu-24.04-arm, os: ubuntu, flavor: arm, cc: clang, flags: -D CMAKE_BUILD_TYPE=RelWithDebInfo },
|
# { 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-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: 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 },
|
{ runner: ubuntu-24.04, os: ubuntu, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON },
|
||||||
@@ -124,17 +124,12 @@ jobs:
|
|||||||
build: { flavor: puc-lua }
|
build: { flavor: puc-lua }
|
||||||
- test: oldtest
|
- test: oldtest
|
||||||
build: { flavor: tsan }
|
build: { flavor: tsan }
|
||||||
- test: unittest
|
|
||||||
build: { runner: ubuntu-24.04-arm }
|
|
||||||
- test: oldtest
|
|
||||||
build: { runner: ubuntu-24.04-arm }
|
|
||||||
runs-on: ${{ matrix.build.runner }}
|
runs-on: ${{ matrix.build.runner }}
|
||||||
timeout-minutes: 45
|
timeout-minutes: 45
|
||||||
env:
|
env:
|
||||||
CC: ${{ matrix.build.cc }}
|
CC: ${{ matrix.build.cc }}
|
||||||
NVIM_TEST_INTEG: ${{ matrix.build.flavor == 'release' && '1' || '0' }}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
with:
|
with:
|
||||||
install_flags: "--test"
|
install_flags: "--test"
|
||||||
@@ -206,35 +201,16 @@ jobs:
|
|||||||
name: Show logs
|
name: Show logs
|
||||||
run: cat $(find "$LOG_DIR" -type f)
|
run: cat $(find "$LOG_DIR" -type f)
|
||||||
|
|
||||||
zig-build:
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
timeout-minutes: 45
|
|
||||||
name: build using zig build (linux)
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v5
|
|
||||||
- uses: mlugg/setup-zig@v2
|
|
||||||
with:
|
|
||||||
version: 0.14.1
|
|
||||||
- run: sudo apt-get install -y inotify-tools
|
|
||||||
- run: zig build test_nlua0
|
|
||||||
- run: zig build nvim && ./zig-out/bin/nvim --version
|
|
||||||
- run: zig build unittest
|
|
||||||
- run: zig build functionaltest
|
|
||||||
# `zig build nvim` uses a lua script for doctags in order to support cross-compiling
|
|
||||||
# compare with the builtin generator that they match
|
|
||||||
- run: cd runtime; ../zig-out/bin/nvim -u NONE -i NONE -e --headless -c "helptags ++t doc" -c quit
|
|
||||||
- run: diff -u runtime/doc/tags zig-out/runtime/doc/tags
|
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
uses: ./.github/workflows/test_windows.yml
|
uses: ./.github/workflows/test_windows.yml
|
||||||
|
|
||||||
with-external-deps:
|
with-external-deps:
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-24.04
|
||||||
timeout-minutes: 10
|
timeout-minutes: 10
|
||||||
env:
|
env:
|
||||||
CC: gcc
|
CC: gcc
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
2
.github/workflows/test_windows.yml
vendored
2
.github/workflows/test_windows.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
test: [functional, old]
|
test: [functional, old]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/setup
|
- uses: ./.github/actions/setup
|
||||||
|
|
||||||
- name: Build deps
|
- name: Build deps
|
||||||
|
4
.github/workflows/vim_patches.yml
vendored
4
.github/workflows/vim_patches.yml
vendored
@@ -15,11 +15,11 @@ jobs:
|
|||||||
VERSION_BRANCH: marvim/ci-version-update
|
VERSION_BRANCH: marvim/ci-version-update
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
repository: vim/vim
|
repository: vim/vim
|
||||||
path: ${{ env.VIM_SOURCE_DIR }}
|
path: ${{ env.VIM_SOURCE_DIR }}
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,8 +10,7 @@ compile_commands.json
|
|||||||
/.idea/
|
/.idea/
|
||||||
|
|
||||||
# Build/deps dir
|
# Build/deps dir
|
||||||
/.zig-cache/
|
/build/
|
||||||
/zig-out/
|
|
||||||
/.deps/
|
/.deps/
|
||||||
/tmp/
|
/tmp/
|
||||||
/.clangd/
|
/.clangd/
|
||||||
|
@@ -49,7 +49,6 @@ exclude_files = {
|
|||||||
'runtime/lua/vim/_meta/vimfn.lua',
|
'runtime/lua/vim/_meta/vimfn.lua',
|
||||||
'runtime/lua/vim/_meta/api.lua',
|
'runtime/lua/vim/_meta/api.lua',
|
||||||
'runtime/lua/vim/re.lua',
|
'runtime/lua/vim/re.lua',
|
||||||
'runtime/lua/uv/_meta.lua',
|
|
||||||
'runtime/lua/coxpcall.lua',
|
'runtime/lua/coxpcall.lua',
|
||||||
'src/nvim/eval.lua',
|
'src/nvim/eval.lua',
|
||||||
}
|
}
|
||||||
|
@@ -5,12 +5,13 @@
|
|||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"library": [
|
"library": [
|
||||||
"${3rd}/busted/library"
|
"runtime/lua",
|
||||||
|
"${3rd}/busted/library",
|
||||||
|
"${3rd}/luv/library"
|
||||||
],
|
],
|
||||||
"ignoreDir": [
|
"ignoreDir": [
|
||||||
".deps",
|
"test",
|
||||||
"build",
|
"_vim9script.lua"
|
||||||
"test"
|
|
||||||
],
|
],
|
||||||
"checkThirdParty": "Disable"
|
"checkThirdParty": "Disable"
|
||||||
},
|
},
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
# Alternative settings for special snowflakes like: decorations_spec.lua, multigrid_spec.lua, etc.
|
|
||||||
|
|
||||||
column_width = 140
|
|
||||||
line_endings = "Unix"
|
|
||||||
indent_type = "Spaces"
|
|
||||||
indent_width = 2
|
|
||||||
quote_style = "AutoPreferSingle"
|
|
||||||
call_parentheses = "Input"
|
|
@@ -1,15 +1,14 @@
|
|||||||
build/
|
/build/
|
||||||
.deps/
|
/.deps/
|
||||||
runtime/lua/coxpcall.lua
|
/runtime/lua/coxpcall.lua
|
||||||
runtime/lua/uv/_meta.lua
|
/runtime/lua/vim/_meta
|
||||||
runtime/lua/vim/_meta
|
/runtime/lua/vim/re.lua
|
||||||
runtime/lua/vim/re.lua
|
|
||||||
|
|
||||||
# These are formatted explicitly by the "formatlua2" build task.
|
|
||||||
test/functional/ui/decorations_spec.lua
|
test/functional/ui/decorations_spec.lua
|
||||||
test/functional/ui/float_spec.lua
|
test/functional/ui/float_spec.lua
|
||||||
test/functional/ui/multigrid_spec.lua
|
test/functional/ui/multigrid_spec.lua
|
||||||
test/functional/fixtures/lua/syntax_error.lua
|
/test/functional/fixtures/lua/syntax_error.lua
|
||||||
test/functional/legacy/030_fileformats_spec.lua
|
/test/functional/legacy/030_fileformats_spec.lua
|
||||||
test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
|
/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
|
||||||
test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
|
/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
|
||||||
|
/test/functional/lua/luaeval_spec.lua
|
||||||
|
53
BUILD.md
53
BUILD.md
@@ -165,40 +165,11 @@ https://github.com/cascent/neovim-cygwin was built on Cygwin 2.9.0. Newer `libuv
|
|||||||
mingw32-make install
|
mingw32-make install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows WSL
|
|
||||||
|
|
||||||
Build Ubuntu/Debian linux binary on [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) (Windows Subsystem for Linux).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Install build prerequisites
|
|
||||||
sudo apt-get install ninja-build gettext cmake build-essential
|
|
||||||
|
|
||||||
# Build the linux binary in WSL
|
|
||||||
make CMAKE_BUILD_TYPE=RelWithDebInfo
|
|
||||||
|
|
||||||
# Install the linux binary in WSL (with `<arch>` either `x86_64` or `arm64`)
|
|
||||||
cd build && cpack -G DEB && sudo dpkg -i nvim-linux-<arch>.deb
|
|
||||||
|
|
||||||
# Verify the installation
|
|
||||||
nvim --version && which nvim # should be debug build in /usr/bin/nvim
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note**: If you encounter linker errors or segfaults during the build, Windows libraries in your PATH may be interfering. Use a clean PATH to avoid conflicts:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" make CMAKE_BUILD_TYPE=RelWithDebInfo
|
|
||||||
```
|
|
||||||
|
|
||||||
## Localization
|
## Localization
|
||||||
|
|
||||||
### Localization build
|
### Localization build
|
||||||
|
|
||||||
Translations are turned off by default. Enable by building Nvim with the CMake flag `ENABLE_TRANSLATIONS=ON`.
|
A normal build will create `.mo` files in `build/src/nvim/po`.
|
||||||
Doing this will create `.mo` files in `build/src/nvim/po`. Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
make CMAKE_EXTRA_FLAGS="-DENABLE_TRANSLATIONS=ON"
|
|
||||||
```
|
|
||||||
|
|
||||||
* If you see `msgfmt: command not found`, you need to install [`gettext`](http://en.wikipedia.org/wiki/Gettext). On most systems, the package is just called `gettext`.
|
* If you see `msgfmt: command not found`, you need to install [`gettext`](http://en.wikipedia.org/wiki/Gettext). On most systems, the package is just called `gettext`.
|
||||||
|
|
||||||
@@ -252,7 +223,7 @@ rebuild:
|
|||||||
|
|
||||||
## Third-party dependencies
|
## Third-party dependencies
|
||||||
|
|
||||||
Reference the [Debian package](https://packages.debian.org/sid/source/neovim) (or alternatively, the [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/n/neovim.rb)) for the precise list of dependencies/versions.
|
Reference the [Debian package](https://packages.debian.org/sid/source/neovim) (or alternatively, the [Homebrew formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/neovim.rb)) for the precise list of dependencies/versions.
|
||||||
|
|
||||||
To build the bundled dependencies using CMake:
|
To build the bundled dependencies using CMake:
|
||||||
|
|
||||||
@@ -302,7 +273,7 @@ podman run \
|
|||||||
-v "$PWD:/workdir" \
|
-v "$PWD:/workdir" \
|
||||||
-w /workdir \
|
-w /workdir \
|
||||||
alpine:latest \
|
alpine:latest \
|
||||||
bash -c 'apk add build-base cmake coreutils curl gettext-tiny-dev git && make CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"'
|
bash -c 'apk add build-base cmake coreutils curl gettext-tiny-dev && make CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"'
|
||||||
```
|
```
|
||||||
|
|
||||||
The resulting binary in `build/bin/nvim` will have all the dependencies statically linked:
|
The resulting binary in `build/bin/nvim` will have all the dependencies statically linked:
|
||||||
@@ -346,31 +317,31 @@ Platform-specific requirements are listed below.
|
|||||||
### Ubuntu / Debian
|
### Ubuntu / Debian
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
sudo apt-get install ninja-build gettext cmake curl build-essential git
|
sudo apt-get install ninja-build gettext cmake curl build-essential
|
||||||
```
|
```
|
||||||
|
|
||||||
### RHEL / Fedora
|
### RHEL / Fedora
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo dnf -y install ninja-build cmake gcc make gettext curl glibc-gconv-extra git
|
sudo dnf -y install ninja-build cmake gcc make gettext curl glibc-gconv-extra
|
||||||
```
|
```
|
||||||
|
|
||||||
### openSUSE
|
### openSUSE
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo zypper install ninja cmake gcc-c++ gettext-tools curl git
|
sudo zypper install ninja cmake gcc-c++ gettext-tools curl
|
||||||
```
|
```
|
||||||
|
|
||||||
### Arch Linux
|
### Arch Linux
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo pacman -S base-devel cmake ninja curl git
|
sudo pacman -S base-devel cmake ninja curl
|
||||||
```
|
```
|
||||||
|
|
||||||
### Alpine Linux
|
### Alpine Linux
|
||||||
|
|
||||||
```
|
```
|
||||||
apk add build-base cmake coreutils curl gettext-tiny-dev git
|
apk add build-base cmake coreutils curl gettext-tiny-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Void Linux
|
### Void Linux
|
||||||
@@ -434,7 +405,7 @@ or a specific SHA1 like `--override-input neovim-src github:neovim/neovim/89dc8f
|
|||||||
### FreeBSD
|
### FreeBSD
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo pkg install cmake gmake sha wget gettext curl git
|
sudo pkg install cmake gmake sha wget gettext curl
|
||||||
```
|
```
|
||||||
|
|
||||||
If you get an error regarding a `sha256sum` mismatch, where the actual SHA-256 hash is `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, then this is your issue (that's the `sha256sum` of an empty file).
|
If you get an error regarding a `sha256sum` mismatch, where the actual SHA-256 hash is `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`, then this is your issue (that's the `sha256sum` of an empty file).
|
||||||
@@ -442,7 +413,7 @@ If you get an error regarding a `sha256sum` mismatch, where the actual SHA-256 h
|
|||||||
### OpenBSD
|
### OpenBSD
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
doas pkg_add gmake cmake curl gettext-tools git
|
doas pkg_add gmake cmake curl gettext-tools
|
||||||
```
|
```
|
||||||
|
|
||||||
Build can sometimes fail when using the top level `Makefile`, apparently due to some third-party component (see [#2445-comment](https://github.com/neovim/neovim/issues/2445#issuecomment-108124236)). The following instructions use CMake:
|
Build can sometimes fail when using the top level `Makefile`, apparently due to some third-party component (see [#2445-comment](https://github.com/neovim/neovim/issues/2445#issuecomment-108124236)). The following instructions use CMake:
|
||||||
@@ -467,7 +438,7 @@ gmake
|
|||||||
2. Install [Homebrew](http://brew.sh)
|
2. Install [Homebrew](http://brew.sh)
|
||||||
3. Install Neovim build dependencies:
|
3. Install Neovim build dependencies:
|
||||||
```
|
```
|
||||||
brew install ninja cmake gettext curl git
|
brew install ninja cmake gettext curl
|
||||||
```
|
```
|
||||||
- **Note**: If you see Wget certificate errors (for older macOS versions less than 10.10):
|
- **Note**: If you see Wget certificate errors (for older macOS versions less than 10.10):
|
||||||
```sh
|
```sh
|
||||||
@@ -485,7 +456,7 @@ gmake
|
|||||||
2. Install [MacPorts](http://www.macports.org)
|
2. Install [MacPorts](http://www.macports.org)
|
||||||
3. Install Neovim build dependencies:
|
3. Install Neovim build dependencies:
|
||||||
```
|
```
|
||||||
sudo port install ninja cmake gettext git
|
sudo port install ninja cmake gettext
|
||||||
```
|
```
|
||||||
- **Note**: If you see Wget certificate errors (for older macOS versions less than 10.10):
|
- **Note**: If you see Wget certificate errors (for older macOS versions less than 10.10):
|
||||||
```sh
|
```sh
|
||||||
|
@@ -35,11 +35,6 @@ include(InstallHelpers)
|
|||||||
include(PreventInTreeBuilds)
|
include(PreventInTreeBuilds)
|
||||||
include(Util)
|
include(Util)
|
||||||
|
|
||||||
if(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
|
|
||||||
# Auto-create a .gitignore in the specified "build" directory.
|
|
||||||
file(GENERATE OUTPUT .gitignore CONTENT "*")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# User settings
|
# User settings
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@@ -145,19 +140,19 @@ endif()
|
|||||||
# If not in a git repo (e.g., a tarball) these tokens define the complete
|
# If not in a git repo (e.g., a tarball) these tokens define the complete
|
||||||
# version string, else they are combined with the result of `git describe`.
|
# version string, else they are combined with the result of `git describe`.
|
||||||
set(NVIM_VERSION_MAJOR 0)
|
set(NVIM_VERSION_MAJOR 0)
|
||||||
set(NVIM_VERSION_MINOR 12)
|
set(NVIM_VERSION_MINOR 11)
|
||||||
set(NVIM_VERSION_PATCH 0)
|
set(NVIM_VERSION_PATCH 3)
|
||||||
set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers
|
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
|
||||||
|
|
||||||
# API level
|
# API level
|
||||||
set(NVIM_API_LEVEL 14) # Bump this after any API/stdlib change.
|
set(NVIM_API_LEVEL 13) # Bump this after any API/stdlib change.
|
||||||
set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change.
|
set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change.
|
||||||
set(NVIM_API_PRERELEASE true)
|
set(NVIM_API_PRERELEASE false)
|
||||||
|
|
||||||
# We _want_ assertions in RelWithDebInfo build-type.
|
# We _want_ assertions in RelWithDebInfo build-type.
|
||||||
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG)
|
if(CMAKE_C_FLAGS_RELWITHDEBINFO MATCHES DNDEBUG)
|
||||||
string(REPLACE "-DNDEBUG" "-DRELDEBUG" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||||
string(REPLACE "/DNDEBUG" "/DRELDEBUG" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
string(REPLACE "/DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||||
string(REPLACE " " " " CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") # Remove duplicate whitespace
|
string(REPLACE " " " " CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") # Remove duplicate whitespace
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -241,7 +236,7 @@ set(STYLUA_DIRS runtime scripts src test contrib)
|
|||||||
add_glob_target(
|
add_glob_target(
|
||||||
TARGET lintlua-luacheck
|
TARGET lintlua-luacheck
|
||||||
COMMAND $<TARGET_FILE:nvim_bin>
|
COMMAND $<TARGET_FILE:nvim_bin>
|
||||||
FLAGS -ll ${PROJECT_SOURCE_DIR}/test/lua_runner.lua ${CMAKE_BINARY_DIR}/usr/share/lua/5.1 luacheck -q
|
FLAGS -ll ${PROJECT_SOURCE_DIR}/test/lua_runner.lua ${CMAKE_BINARY_DIR}/usr luacheck -q
|
||||||
GLOB_DIRS runtime scripts src test
|
GLOB_DIRS runtime scripts src test
|
||||||
GLOB_PAT *.lua
|
GLOB_PAT *.lua
|
||||||
TOUCH_STRATEGY PER_DIR)
|
TOUCH_STRATEGY PER_DIR)
|
||||||
@@ -254,16 +249,6 @@ add_glob_target(
|
|||||||
GLOB_DIRS ${STYLUA_DIRS}
|
GLOB_DIRS ${STYLUA_DIRS}
|
||||||
GLOB_PAT *.lua
|
GLOB_PAT *.lua
|
||||||
TOUCH_STRATEGY PER_DIR)
|
TOUCH_STRATEGY PER_DIR)
|
||||||
# Special handling of some files (which are ignored in .styluaignore).
|
|
||||||
# Workaround because stylua doesn't(?) support file-specific settings.
|
|
||||||
add_custom_target(lintlua-stylua2
|
|
||||||
COMMAND ${STYLUA_PRG} --config-path "${PROJECT_SOURCE_DIR}/.stylua2.toml"
|
|
||||||
--color=always --check
|
|
||||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/decorations_spec.lua"
|
|
||||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/float_spec.lua"
|
|
||||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/multigrid_spec.lua"
|
|
||||||
)
|
|
||||||
add_dependencies(lintlua-stylua lintlua-stylua2)
|
|
||||||
|
|
||||||
add_custom_target(lintlua)
|
add_custom_target(lintlua)
|
||||||
add_dependencies(lintlua lintlua-luacheck lintlua-stylua)
|
add_dependencies(lintlua lintlua-luacheck lintlua-stylua)
|
||||||
@@ -277,7 +262,7 @@ add_glob_target(
|
|||||||
TOUCH_STRATEGY PER_DIR)
|
TOUCH_STRATEGY PER_DIR)
|
||||||
|
|
||||||
add_custom_target(lintcommit
|
add_custom_target(lintcommit
|
||||||
COMMAND $<TARGET_FILE:nvim_bin> --clean -l ${PROJECT_SOURCE_DIR}/scripts/lintcommit.lua main)
|
COMMAND $<TARGET_FILE:nvim_bin> -u NONE -l ${PROJECT_SOURCE_DIR}/scripts/lintcommit.lua main)
|
||||||
add_dependencies(lintcommit nvim_bin)
|
add_dependencies(lintcommit nvim_bin)
|
||||||
|
|
||||||
add_custom_target(lint)
|
add_custom_target(lint)
|
||||||
@@ -291,15 +276,7 @@ add_glob_target(
|
|||||||
GLOB_DIRS ${STYLUA_DIRS}
|
GLOB_DIRS ${STYLUA_DIRS}
|
||||||
GLOB_PAT *.lua
|
GLOB_PAT *.lua
|
||||||
TOUCH_STRATEGY PER_DIR)
|
TOUCH_STRATEGY PER_DIR)
|
||||||
# Special handling of some files (which are ignored in .styluaignore).
|
|
||||||
# Workaround because stylua doesn't(?) support file-specific settings.
|
|
||||||
add_custom_target(formatlua2
|
|
||||||
COMMAND ${STYLUA_PRG} --config-path "${PROJECT_SOURCE_DIR}/.stylua2.toml"
|
|
||||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/decorations_spec.lua"
|
|
||||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/float_spec.lua"
|
|
||||||
"${PROJECT_SOURCE_DIR}/test/functional/ui/multigrid_spec.lua"
|
|
||||||
)
|
|
||||||
add_dependencies(formatlua formatlua2)
|
|
||||||
add_custom_target(format)
|
add_custom_target(format)
|
||||||
add_dependencies(format formatc formatlua)
|
add_dependencies(format formatc formatlua)
|
||||||
|
|
||||||
@@ -346,13 +323,13 @@ else()
|
|||||||
add_custom_target(lua_dev_deps)
|
add_custom_target(lua_dev_deps)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm|aarch")
|
if (CMAKE_SYSTEM_PROCESSOR MATCHES arm64)
|
||||||
set(LUALS_ARCH arm64)
|
set(LUALS_ARCH arm64)
|
||||||
else()
|
else()
|
||||||
set(LUALS_ARCH x64)
|
set(LUALS_ARCH x64)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(LUALS_VERSION 3.15.0)
|
set(LUALS_VERSION 3.13.9)
|
||||||
set(LUALS "lua-language-server-${LUALS_VERSION}-${CMAKE_SYSTEM_NAME}-${LUALS_ARCH}")
|
set(LUALS "lua-language-server-${LUALS_VERSION}-${CMAKE_SYSTEM_NAME}-${LUALS_ARCH}")
|
||||||
set(LUALS_TARBALL ${LUALS}.tar.gz)
|
set(LUALS_TARBALL ${LUALS}.tar.gz)
|
||||||
set(LUALS_URL https://github.com/LuaLS/lua-language-server/releases/download/${LUALS_VERSION}/${LUALS_TARBALL})
|
set(LUALS_URL https://github.com/LuaLS/lua-language-server/releases/download/${LUALS_VERSION}/${LUALS_TARBALL})
|
||||||
|
@@ -299,7 +299,7 @@ types, etc. See [:help dev-lua-doc][dev-lua-doc].
|
|||||||
- If possible, add type information (`table`, `string`, `number`, ...). Multiple valid types are separated by a bar (`string|table`). Indicate optional parameters via `type|nil`.
|
- If possible, add type information (`table`, `string`, `number`, ...). Multiple valid types are separated by a bar (`string|table`). Indicate optional parameters via `type|nil`.
|
||||||
- If a function in your Lua module should _not_ be documented, add `@nodoc`.
|
- If a function in your Lua module should _not_ be documented, add `@nodoc`.
|
||||||
- If the function is internal or otherwise non-public add `@private`.
|
- If the function is internal or otherwise non-public add `@private`.
|
||||||
- Private functions usually should be underscore-prefixed (named "_foo", not "foo"). Prefixing with an underscore implies `@nodoc`.
|
- Private functions usually should be underscore-prefixed (named "_foo", not "foo").
|
||||||
- Mark deprecated functions with `@deprecated`.
|
- Mark deprecated functions with `@deprecated`.
|
||||||
|
|
||||||
Third-party dependencies
|
Third-party dependencies
|
||||||
|
12
INSTALL.md
12
INSTALL.md
@@ -62,17 +62,15 @@ Several Neovim GUIs are available from scoop (extras): [scoop.sh/#/apps?q=neovim
|
|||||||
|
|
||||||
- Add the `bin` folder (e.g. `C:\Program Files\nvim\bin`) to your PATH.
|
- Add the `bin` folder (e.g. `C:\Program Files\nvim\bin`) to your PATH.
|
||||||
- This makes it easy to run `nvim` from anywhere.
|
- This makes it easy to run `nvim` from anywhere.
|
||||||
- If `:set spell` does not work, create the `%LOCALAPPDATA%/nvim-data/site/spell` folder.
|
- 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
|
You can then copy your spell files over (for English, located
|
||||||
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.spl) and
|
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.spl) and
|
||||||
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.sug));
|
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.sug));
|
||||||
- For Python plugins you need the `pynvim` module. Installation via uv
|
- For Python plugins you need the `pynvim` module. "Virtual envs" are recommended. After activating the virtual env do `pip install pynvim` (in *both*). Edit your `init.vim` so that it contains the path to the env's Python executable:
|
||||||
(https://docs.astral.sh/uv/) is recommended; the `--upgrade` switch ensures
|
```vim
|
||||||
installation of the latest version:
|
let g:python3_host_prog='C:/Users/foo/Envs/neovim3/Scripts/python.exe'
|
||||||
```
|
```
|
||||||
uv tool install --upgrade pynvim
|
- Run `:checkhealth` and read `:help provider-python`.
|
||||||
```
|
|
||||||
- Run `:checkhealth` and read `:help provider-python` for more details.
|
|
||||||
- **init.vim ("vimrc"):** If you already have Vim installed you can copy `%userprofile%\_vimrc` to `%userprofile%\AppData\Local\nvim\init.vim` to use your Vim config with Neovim.
|
- **init.vim ("vimrc"):** If you already have Vim installed you can copy `%userprofile%\_vimrc` to `%userprofile%\AppData\Local\nvim\init.vim` to use your Vim config with Neovim.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -289,8 +289,3 @@ IV) It is not allowed to remove this license from the distribution of the Vim
|
|||||||
license for previous Vim releases instead of the license that they came
|
license for previous Vim releases instead of the license that they came
|
||||||
with, at your option.
|
with, at your option.
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
In addition, different license conditions may apply to some runtime files
|
|
||||||
included with Vim; these will be specified in the header of each respective
|
|
||||||
file.
|
|
||||||
|
@@ -81,7 +81,7 @@ When a (non-experimental) feature is slated to be removed it should:
|
|||||||
as described for Lua features.
|
as described for Lua features.
|
||||||
- `vim.deprecate(…, 'x.y.z')` where major version `x` is greater than the
|
- `vim.deprecate(…, 'x.y.z')` where major version `x` is greater than the
|
||||||
current Nvim major version, is always treated as _soft_ deprecation.
|
current Nvim major version, is always treated as _soft_ deprecation.
|
||||||
2. Be _hard_ deprecated in a release following the release in which it was soft deprecated.
|
2. Be _hard_ deprecated in a following a release in which it was soft deprecated.
|
||||||
- Use of the deprecated feature will still work but should issue a warning.
|
- Use of the deprecated feature will still work but should issue a warning.
|
||||||
- Features implemented in C will need bespoke implementations to communicate
|
- Features implemented in C will need bespoke implementations to communicate
|
||||||
to users that the feature is deprecated.
|
to users that the feature is deprecated.
|
||||||
@@ -127,9 +127,7 @@ Some can be auto-bumped by `scripts/bump_deps.lua`.
|
|||||||
* [LuaJIT](https://github.com/LuaJIT/LuaJIT)
|
* [LuaJIT](https://github.com/LuaJIT/LuaJIT)
|
||||||
* [Lua](https://www.lua.org/download.html)
|
* [Lua](https://www.lua.org/download.html)
|
||||||
* [Luv](https://github.com/luvit/luv)
|
* [Luv](https://github.com/luvit/luv)
|
||||||
* When bumping, also sync
|
* When bumping, also sync [our bundled documentation](https://github.com/neovim/neovim/blob/master/runtime/doc/luvref.txt) with [the upstream documentation](https://github.com/luvit/luv/blob/master/docs.md).
|
||||||
- [our bundled meta file](https://github.com/neovim/neovim/blob/master/runtime/lua/uv/_meta.lua) with [the upstream meta file](https://github.com/luvit/luv/blob/master/docs/meta.lua);
|
|
||||||
- [our bundled documentation](https://github.com/neovim/neovim/blob/master/runtime/doc/luvref.txt) with [the upstream documentation](https://github.com/luvit/luv/blob/master/docs/docs.md).
|
|
||||||
* [gettext](https://ftp.gnu.org/pub/gnu/gettext/)
|
* [gettext](https://ftp.gnu.org/pub/gnu/gettext/)
|
||||||
* [libiconv](https://ftp.gnu.org/pub/gnu/libiconv)
|
* [libiconv](https://ftp.gnu.org/pub/gnu/libiconv)
|
||||||
* [libuv](https://github.com/libuv/libuv)
|
* [libuv](https://github.com/libuv/libuv)
|
||||||
@@ -154,7 +152,7 @@ These dependencies are "vendored" (inlined), we must update the sources manually
|
|||||||
* `src/nvim/tui/terminfo_defs.h`: terminfo definitions
|
* `src/nvim/tui/terminfo_defs.h`: terminfo definitions
|
||||||
* Run `scripts/update_terminfo.sh` to update these definitions.
|
* Run `scripts/update_terminfo.sh` to update these definitions.
|
||||||
* `runtime/lua/vim/lsp/_meta/protocol.lua`: LSP specification
|
* `runtime/lua/vim/lsp/_meta/protocol.lua`: LSP specification
|
||||||
* Run `src/gen/gen_lsp.lua` to update.
|
* Run `scripts/gen_lsp.lua` to update.
|
||||||
* `runtime/lua/vim/_meta/lpeg.lua`: LPeg definitions.
|
* `runtime/lua/vim/_meta/lpeg.lua`: LPeg definitions.
|
||||||
* Refer to [`LuaCATS/lpeg`](https://github.com/LuaCATS/lpeg) for updates.
|
* Refer to [`LuaCATS/lpeg`](https://github.com/LuaCATS/lpeg) for updates.
|
||||||
* Update the git SHA revision from which the documentation was taken.
|
* Update the git SHA revision from which the documentation was taken.
|
||||||
|
6
Makefile
6
Makefile
@@ -182,9 +182,3 @@ appimage-%:
|
|||||||
bash scripts/genappimage.sh $*
|
bash scripts/genappimage.sh $*
|
||||||
|
|
||||||
.PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST)
|
.PHONY: test clean distclean nvim libnvim cmake deps install appimage checkprefix benchmark $(FORMAT) $(LINT) $(TEST)
|
||||||
|
|
||||||
.PHONY: emmylua-check
|
|
||||||
emmylua-check:
|
|
||||||
-emmylua_check runtime/lua \
|
|
||||||
--config .luarc.json \
|
|
||||||
--config .emmyrc.json
|
|
||||||
|
462
build.zig
462
build.zig
@@ -1,462 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
const LazyPath = std.Build.LazyPath;
|
|
||||||
const build_lua = @import("src/build_lua.zig");
|
|
||||||
const gen = @import("src/gen/gen_steps.zig");
|
|
||||||
const runtime = @import("runtime/gen_runtime.zig");
|
|
||||||
const tests = @import("test/run_tests.zig");
|
|
||||||
|
|
||||||
const version = struct {
|
|
||||||
const major = 0;
|
|
||||||
const minor = 12;
|
|
||||||
const patch = 0;
|
|
||||||
const prerelease = "-dev";
|
|
||||||
|
|
||||||
const api_level = 14;
|
|
||||||
const api_level_compat = 0;
|
|
||||||
const api_prerelease = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(bfredl): this is for an upstream issue
|
|
||||||
pub fn lazyArtifact(d: *std.Build.Dependency, name: []const u8) ?*std.Build.Step.Compile {
|
|
||||||
var found: ?*std.Build.Step.Compile = null;
|
|
||||||
for (d.builder.install_tls.step.dependencies.items) |dep_step| {
|
|
||||||
const inst = dep_step.cast(std.Build.Step.InstallArtifact) orelse continue;
|
|
||||||
if (std.mem.eql(u8, inst.artifact.name, name)) {
|
|
||||||
if (found != null) std.debug.panic("artifact name '{s}' is ambiguous", .{name});
|
|
||||||
found = inst.artifact;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const t = target.result;
|
|
||||||
const os_tag = t.os.tag;
|
|
||||||
const is_windows = (os_tag == .windows);
|
|
||||||
const is_linux = (os_tag == .linux);
|
|
||||||
const is_darwin = os_tag.isDarwin();
|
|
||||||
const modern_unix = is_darwin or os_tag.isBSD() or is_linux;
|
|
||||||
|
|
||||||
const cross_compiling = b.option(bool, "cross", "cross compile") orelse false;
|
|
||||||
// TODO(bfredl): option to set nlua0 target explicitly when cross compiling?
|
|
||||||
const target_host = if (cross_compiling) b.graph.host else target;
|
|
||||||
const optimize_host = .ReleaseSafe;
|
|
||||||
|
|
||||||
// puc lua 5.1 is not ReleaseSafe "safe"
|
|
||||||
const optimize_lua = if (optimize == .Debug or optimize == .ReleaseSafe) .ReleaseSmall else optimize;
|
|
||||||
|
|
||||||
const arch = t.cpu.arch;
|
|
||||||
const default_luajit = (is_linux and arch == .x86_64) or (is_darwin and arch == .aarch64);
|
|
||||||
const use_luajit = b.option(bool, "luajit", "use luajit") orelse default_luajit;
|
|
||||||
const host_use_luajit = if (cross_compiling) false else use_luajit;
|
|
||||||
const E = enum { luajit, lua51 };
|
|
||||||
|
|
||||||
const ziglua = b.dependency("zlua", .{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize_lua,
|
|
||||||
.lang = if (use_luajit) E.luajit else E.lua51,
|
|
||||||
.shared = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ziglua_host = if (cross_compiling) b.dependency("zlua", .{
|
|
||||||
.target = target_host,
|
|
||||||
.optimize = optimize_lua,
|
|
||||||
.lang = if (host_use_luajit) E.luajit else E.lua51,
|
|
||||||
.shared = false,
|
|
||||||
}) else ziglua;
|
|
||||||
|
|
||||||
const lpeg = b.dependency("lpeg", .{});
|
|
||||||
|
|
||||||
const iconv = if (is_windows or is_darwin) b.lazyDependency("libiconv", .{ .target = target, .optimize = optimize }) else null;
|
|
||||||
|
|
||||||
// this is currently not necessary, as ziglua currently doesn't use lazy dependencies
|
|
||||||
// to circumvent ziglua.artifact() failing in a bad way.
|
|
||||||
const lua = lazyArtifact(ziglua, "lua") orelse return;
|
|
||||||
if (cross_compiling) {
|
|
||||||
_ = lazyArtifact(ziglua_host, "lua") orelse return;
|
|
||||||
}
|
|
||||||
// const lua = ziglua.artifact("lua");
|
|
||||||
|
|
||||||
const libuv_dep = b.dependency("libuv", .{ .target = target, .optimize = optimize });
|
|
||||||
const libuv = libuv_dep.artifact("uv");
|
|
||||||
const libluv = try build_lua.build_libluv(b, target, optimize, lua, libuv);
|
|
||||||
|
|
||||||
const libluv_host = if (cross_compiling) libluv_host: {
|
|
||||||
const libuv_dep_host = b.dependency("libuv", .{ .target = target_host, .optimize = optimize_host });
|
|
||||||
const libuv_host = libuv_dep_host.artifact("uv");
|
|
||||||
break :libluv_host try build_lua.build_libluv(b, target_host, optimize_host, ziglua_host.artifact("lua"), libuv_host);
|
|
||||||
} else libluv;
|
|
||||||
|
|
||||||
const utf8proc = b.dependency("utf8proc", .{ .target = target, .optimize = optimize });
|
|
||||||
const unibilium = b.dependency("unibilium", .{ .target = target, .optimize = optimize });
|
|
||||||
// TODO(bfredl): fix upstream bugs with UBSAN
|
|
||||||
const treesitter = b.dependency("treesitter", .{ .target = target, .optimize = .ReleaseFast });
|
|
||||||
|
|
||||||
const nlua0 = build_lua.build_nlua0(b, target_host, optimize_host, host_use_luajit, ziglua_host, lpeg, libluv_host);
|
|
||||||
|
|
||||||
// usual caveat emptor: might need to force a rebuild if the only change is
|
|
||||||
// addition of new .c files, as those are not seen by any hash
|
|
||||||
const subdirs = [_][]const u8{
|
|
||||||
"", // src/nvim itself
|
|
||||||
"os/",
|
|
||||||
"api/",
|
|
||||||
"api/private/",
|
|
||||||
"msgpack_rpc/",
|
|
||||||
"tui/",
|
|
||||||
"tui/termkey/",
|
|
||||||
"event/",
|
|
||||||
"eval/",
|
|
||||||
"lib/",
|
|
||||||
"lua/",
|
|
||||||
"viml/",
|
|
||||||
"viml/parser/",
|
|
||||||
"vterm/",
|
|
||||||
};
|
|
||||||
|
|
||||||
// source names _relative_ src/nvim/, not including other src/ subdircs
|
|
||||||
var nvim_sources = try std.ArrayList(gen.SourceItem).initCapacity(b.allocator, 100);
|
|
||||||
var nvim_headers = try std.ArrayList([]u8).initCapacity(b.allocator, 100);
|
|
||||||
|
|
||||||
// both source headers and the {module}.h.generated.h files
|
|
||||||
var api_headers = try std.ArrayList(std.Build.LazyPath).initCapacity(b.allocator, 10);
|
|
||||||
|
|
||||||
// TODO(bfredl): these should just become subdirs..
|
|
||||||
const windows_only = [_][]const u8{ "pty_proc_win.c", "pty_proc_win.h", "pty_conpty_win.c", "pty_conpty_win.h", "os_win_console.c", "win_defs.h" };
|
|
||||||
const unix_only = [_][]const u8{ "unix_defs.h", "pty_proc_unix.c", "pty_proc_unix.h" };
|
|
||||||
const exclude_list = if (is_windows) &unix_only else &windows_only;
|
|
||||||
|
|
||||||
const src_dir = b.build_root.handle;
|
|
||||||
for (subdirs) |s| {
|
|
||||||
var dir = try src_dir.openDir(b.fmt("src/nvim/{s}", .{s}), .{ .iterate = true });
|
|
||||||
defer dir.close();
|
|
||||||
var it = dir.iterateAssumeFirstIteration();
|
|
||||||
const api_export = std.mem.eql(u8, s, "api/");
|
|
||||||
const os_check = std.mem.eql(u8, s, "os/");
|
|
||||||
entries: while (try it.next()) |entry| {
|
|
||||||
if (entry.name.len < 3) continue;
|
|
||||||
if (entry.name[0] < 'a' or entry.name[0] > 'z') continue;
|
|
||||||
if (os_check) {
|
|
||||||
for (exclude_list) |name| {
|
|
||||||
if (std.mem.eql(u8, name, entry.name)) {
|
|
||||||
continue :entries;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) {
|
|
||||||
try nvim_sources.append(.{ .name = b.fmt("{s}{s}", .{ s, entry.name }), .api_export = api_export });
|
|
||||||
}
|
|
||||||
if (std.mem.eql(u8, ".h", entry.name[entry.name.len - 2 ..])) {
|
|
||||||
try nvim_headers.append(b.fmt("{s}{s}", .{ s, entry.name }));
|
|
||||||
if (api_export and !std.mem.eql(u8, "ui_events.in.h", entry.name)) {
|
|
||||||
try api_headers.append(b.path(b.fmt("src/nvim/{s}{s}", .{ s, entry.name })));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const support_unittests = use_luajit;
|
|
||||||
|
|
||||||
const gen_config = b.addWriteFiles();
|
|
||||||
|
|
||||||
const version_lua = gen_config.add("nvim_version.lua", lua_version_info(b));
|
|
||||||
|
|
||||||
var config_str = b.fmt("zig build -Doptimize={s}", .{@tagName(optimize)});
|
|
||||||
if (cross_compiling) {
|
|
||||||
config_str = b.fmt("{s} -Dcross -Dtarget={s} (host: {s})", .{ config_str, try t.linuxTriple(b.allocator), try b.graph.host.result.linuxTriple(b.allocator) });
|
|
||||||
}
|
|
||||||
|
|
||||||
const versiondef_step = b.addConfigHeader(.{ .style = .{ .cmake = b.path("cmake.config/versiondef.h.in") } }, .{
|
|
||||||
.NVIM_VERSION_MAJOR = version.major,
|
|
||||||
.NVIM_VERSION_MINOR = version.minor,
|
|
||||||
.NVIM_VERSION_PATCH = version.patch,
|
|
||||||
.NVIM_VERSION_PRERELEASE = version.prerelease,
|
|
||||||
.NVIM_VERSION_MEDIUM = "",
|
|
||||||
.VERSION_STRING = "TODO", // TODO(bfredl): not sure what to put here. summary already in "config_str"
|
|
||||||
.CONFIG = config_str,
|
|
||||||
});
|
|
||||||
_ = gen_config.addCopyFile(versiondef_step.getOutput(), "auto/versiondef.h"); // run_preprocessor() workaronnd
|
|
||||||
|
|
||||||
const ptrwidth = t.ptrBitWidth() / 8;
|
|
||||||
const sysconfig_step = b.addConfigHeader(.{ .style = .{ .cmake = b.path("cmake.config/config.h.in") } }, .{
|
|
||||||
.SIZEOF_INT = t.cTypeByteSize(.int),
|
|
||||||
.SIZEOF_INTMAX_T = t.cTypeByteSize(.longlong), // TODO
|
|
||||||
.SIZEOF_LONG = t.cTypeByteSize(.long),
|
|
||||||
.SIZEOF_SIZE_T = ptrwidth,
|
|
||||||
.SIZEOF_VOID_PTR = ptrwidth,
|
|
||||||
|
|
||||||
.PROJECT_NAME = "nvim",
|
|
||||||
|
|
||||||
.HAVE__NSGETENVIRON = is_darwin,
|
|
||||||
.HAVE_FD_CLOEXEC = modern_unix,
|
|
||||||
.HAVE_FSEEKO = modern_unix,
|
|
||||||
.HAVE_LANGINFO_H = modern_unix,
|
|
||||||
.HAVE_NL_LANGINFO_CODESET = modern_unix,
|
|
||||||
.HAVE_NL_MSG_CAT_CNTR = t.isGnuLibC(),
|
|
||||||
.HAVE_PWD_FUNCS = modern_unix,
|
|
||||||
.HAVE_READLINK = modern_unix,
|
|
||||||
.HAVE_STRNLEN = modern_unix,
|
|
||||||
.HAVE_STRCASECMP = modern_unix,
|
|
||||||
.HAVE_STRINGS_H = modern_unix,
|
|
||||||
.HAVE_STRNCASECMP = modern_unix,
|
|
||||||
.HAVE_STRPTIME = modern_unix,
|
|
||||||
.HAVE_XATTR = is_linux,
|
|
||||||
.HAVE_SYS_SDT_H = false,
|
|
||||||
.HAVE_SYS_UTSNAME_H = modern_unix,
|
|
||||||
.HAVE_SYS_WAIT_H = false, // unused
|
|
||||||
.HAVE_TERMIOS_H = modern_unix,
|
|
||||||
.HAVE_WORKING_LIBINTL = t.isGnuLibC(),
|
|
||||||
.UNIX = modern_unix,
|
|
||||||
.CASE_INSENSITIVE_FILENAME = is_darwin or is_windows,
|
|
||||||
.HAVE_SYS_UIO_H = modern_unix,
|
|
||||||
.HAVE_READV = modern_unix,
|
|
||||||
.HAVE_DIRFD_AND_FLOCK = modern_unix,
|
|
||||||
.HAVE_FORKPTY = modern_unix and !is_darwin, // also on Darwin but we lack the headers :(
|
|
||||||
.HAVE_BE64TOH = modern_unix and !is_darwin,
|
|
||||||
.ORDER_BIG_ENDIAN = t.cpu.arch.endian() == .big,
|
|
||||||
.ENDIAN_INCLUDE_FILE = "endian.h",
|
|
||||||
.HAVE_EXECINFO_BACKTRACE = modern_unix and !t.isMuslLibC(),
|
|
||||||
.HAVE_BUILTIN_ADD_OVERFLOW = true,
|
|
||||||
.HAVE_WIMPLICIT_FALLTHROUGH_FLAG = true,
|
|
||||||
.HAVE_BITSCANFORWARD64 = null,
|
|
||||||
|
|
||||||
.VTERM_TEST_FILE = "test/vterm_test_output", // TODO(bfredl): revisit when porting libvterm tests
|
|
||||||
});
|
|
||||||
|
|
||||||
_ = gen_config.addCopyFile(sysconfig_step.getOutput(), "auto/config.h"); // run_preprocessor() workaronnd
|
|
||||||
_ = gen_config.add("auto/pathdef.h", b.fmt(
|
|
||||||
\\char *default_vim_dir = "/usr/local/share/nvim";
|
|
||||||
\\char *default_vimruntime_dir = "";
|
|
||||||
\\char *default_lib_dir = "/usr/local/lib/nvim";
|
|
||||||
, .{}));
|
|
||||||
|
|
||||||
// TODO(bfredl): include git version when available
|
|
||||||
const medium = b.fmt("v{}.{}.{}{s}+zig", .{ version.major, version.minor, version.patch, version.prerelease });
|
|
||||||
const versiondef_git = gen_config.add("auto/versiondef_git.h", b.fmt(
|
|
||||||
\\#define NVIM_VERSION_MEDIUM "{s}"
|
|
||||||
\\#define NVIM_VERSION_BUILD "???"
|
|
||||||
\\
|
|
||||||
, .{medium}));
|
|
||||||
|
|
||||||
// TODO(zig): using getEmittedIncludeTree() is ugly af. we want unittests
|
|
||||||
// to reuse the std.build.Module include_path thing
|
|
||||||
const unittest_include_path = [_]LazyPath{
|
|
||||||
b.path("src/"),
|
|
||||||
gen_config.getDirectory(),
|
|
||||||
lua.getEmittedIncludeTree(),
|
|
||||||
libuv.getEmittedIncludeTree(),
|
|
||||||
libluv.getEmittedIncludeTree(),
|
|
||||||
utf8proc.artifact("utf8proc").getEmittedIncludeTree(),
|
|
||||||
unibilium.artifact("unibilium").getEmittedIncludeTree(),
|
|
||||||
treesitter.artifact("tree-sitter").getEmittedIncludeTree(),
|
|
||||||
if (iconv) |dep| dep.artifact("iconv").getEmittedIncludeTree() else b.path("UNUSED_PATH/"),
|
|
||||||
};
|
|
||||||
|
|
||||||
const gen_headers, const funcs_data = try gen.nvim_gen_sources(b, nlua0, &nvim_sources, &nvim_headers, &api_headers, versiondef_git, version_lua);
|
|
||||||
|
|
||||||
const test_config_step = b.addWriteFiles();
|
|
||||||
_ = test_config_step.add("test/cmakeconfig/paths.lua", try test_config(b));
|
|
||||||
|
|
||||||
const test_gen_step = b.step("gen_headers", "debug: output generated headers");
|
|
||||||
const config_install = b.addInstallDirectory(.{ .source_dir = gen_config.getDirectory(), .install_dir = .prefix, .install_subdir = "config/" });
|
|
||||||
test_gen_step.dependOn(&config_install.step);
|
|
||||||
test_gen_step.dependOn(&b.addInstallDirectory(.{ .source_dir = gen_headers.getDirectory(), .install_dir = .prefix, .install_subdir = "headers/" }).step);
|
|
||||||
|
|
||||||
const nvim_exe = b.addExecutable(.{
|
|
||||||
.name = "nvim",
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
nvim_exe.rdynamic = true; // -E
|
|
||||||
|
|
||||||
nvim_exe.linkLibrary(lua);
|
|
||||||
nvim_exe.linkLibrary(libuv);
|
|
||||||
nvim_exe.linkLibrary(libluv);
|
|
||||||
if (iconv) |dep| nvim_exe.linkLibrary(dep.artifact("iconv"));
|
|
||||||
nvim_exe.linkLibrary(utf8proc.artifact("utf8proc"));
|
|
||||||
nvim_exe.linkLibrary(unibilium.artifact("unibilium"));
|
|
||||||
nvim_exe.linkLibrary(treesitter.artifact("tree-sitter"));
|
|
||||||
if (is_windows) {
|
|
||||||
nvim_exe.linkSystemLibrary("netapi32");
|
|
||||||
}
|
|
||||||
nvim_exe.addIncludePath(b.path("src"));
|
|
||||||
nvim_exe.addIncludePath(gen_config.getDirectory());
|
|
||||||
nvim_exe.addIncludePath(gen_headers.getDirectory());
|
|
||||||
build_lua.add_lua_modules(nvim_exe.root_module, lpeg, use_luajit, false);
|
|
||||||
|
|
||||||
var unit_test_sources = try std.ArrayList([]u8).initCapacity(b.allocator, 10);
|
|
||||||
if (support_unittests) {
|
|
||||||
var unit_test_fixtures = try src_dir.openDir("test/unit/fixtures/", .{ .iterate = true });
|
|
||||||
defer unit_test_fixtures.close();
|
|
||||||
var it = unit_test_fixtures.iterateAssumeFirstIteration();
|
|
||||||
while (try it.next()) |entry| {
|
|
||||||
if (entry.name.len < 3) continue;
|
|
||||||
if (std.mem.eql(u8, ".c", entry.name[entry.name.len - 2 ..])) {
|
|
||||||
try unit_test_sources.append(b.fmt("test/unit/fixtures/{s}", .{entry.name}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const src_paths = try b.allocator.alloc([]u8, nvim_sources.items.len + unit_test_sources.items.len);
|
|
||||||
for (nvim_sources.items, 0..) |s, i| {
|
|
||||||
src_paths[i] = b.fmt("src/nvim/{s}", .{s.name});
|
|
||||||
}
|
|
||||||
@memcpy(src_paths[nvim_sources.items.len..], unit_test_sources.items);
|
|
||||||
|
|
||||||
const flags = [_][]const u8{
|
|
||||||
"-std=gnu99",
|
|
||||||
"-DZIG_BUILD",
|
|
||||||
"-D_GNU_SOURCE",
|
|
||||||
if (support_unittests) "-DUNIT_TESTING" else "",
|
|
||||||
if (use_luajit) "" else "-DNVIM_VENDOR_BIT",
|
|
||||||
if (is_windows) "-DMSWIN" else "",
|
|
||||||
if (is_windows) "-DWIN32_LEAN_AND_MEAN" else "",
|
|
||||||
if (is_windows) "-DUTF8PROC_STATIC" else "",
|
|
||||||
};
|
|
||||||
nvim_exe.addCSourceFiles(.{ .files = src_paths, .flags = &flags });
|
|
||||||
|
|
||||||
nvim_exe.addCSourceFiles(.{ .files = &.{
|
|
||||||
"src/xdiff/xdiffi.c",
|
|
||||||
"src/xdiff/xemit.c",
|
|
||||||
"src/xdiff/xhistogram.c",
|
|
||||||
"src/xdiff/xpatience.c",
|
|
||||||
"src/xdiff/xprepare.c",
|
|
||||||
"src/xdiff/xutils.c",
|
|
||||||
"src/cjson/lua_cjson.c",
|
|
||||||
"src/cjson/fpconv.c",
|
|
||||||
"src/cjson/strbuf.c",
|
|
||||||
}, .flags = &flags });
|
|
||||||
|
|
||||||
const nvim_exe_step = b.step("nvim_bin", "only the binary (not a fully working install!)");
|
|
||||||
const nvim_exe_install = b.addInstallArtifact(nvim_exe, .{});
|
|
||||||
|
|
||||||
nvim_exe_step.dependOn(&nvim_exe_install.step);
|
|
||||||
|
|
||||||
const gen_runtime = try runtime.nvim_gen_runtime(b, nlua0, funcs_data);
|
|
||||||
const runtime_install = b.addInstallDirectory(.{ .source_dir = gen_runtime.getDirectory(), .install_dir = .prefix, .install_subdir = "runtime/" });
|
|
||||||
|
|
||||||
const nvim = b.step("nvim", "build the editor");
|
|
||||||
|
|
||||||
nvim.dependOn(&nvim_exe_install.step);
|
|
||||||
nvim.dependOn(&runtime_install.step);
|
|
||||||
|
|
||||||
const lua_dev_deps = b.dependency("lua_dev_deps", .{});
|
|
||||||
|
|
||||||
const test_deps = b.step("test_deps", "test prerequisites");
|
|
||||||
test_deps.dependOn(&nvim_exe_install.step);
|
|
||||||
test_deps.dependOn(&runtime_install.step);
|
|
||||||
|
|
||||||
test_deps.dependOn(test_fixture(b, "shell-test", null, target, optimize));
|
|
||||||
test_deps.dependOn(test_fixture(b, "tty-test", libuv, target, optimize));
|
|
||||||
test_deps.dependOn(test_fixture(b, "pwsh-test", null, target, optimize));
|
|
||||||
test_deps.dependOn(test_fixture(b, "printargs-test", null, target, optimize));
|
|
||||||
test_deps.dependOn(test_fixture(b, "printenv-test", null, target, optimize));
|
|
||||||
test_deps.dependOn(test_fixture(b, "streams-test", libuv, target, optimize));
|
|
||||||
|
|
||||||
const parser_c = b.dependency("treesitter_c", .{ .target = target, .optimize = optimize });
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "c", parser_c.path("."), false, target, optimize));
|
|
||||||
const parser_markdown = b.dependency("treesitter_markdown", .{ .target = target, .optimize = optimize });
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "markdown", parser_markdown.path("tree-sitter-markdown/"), true, target, optimize));
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "markdown_inline", parser_markdown.path("tree-sitter-markdown-inline/"), true, target, optimize));
|
|
||||||
const parser_vim = b.dependency("treesitter_vim", .{ .target = target, .optimize = optimize });
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "vim", parser_vim.path("."), true, target, optimize));
|
|
||||||
const parser_vimdoc = b.dependency("treesitter_vimdoc", .{ .target = target, .optimize = optimize });
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "vimdoc", parser_vimdoc.path("."), false, target, optimize));
|
|
||||||
const parser_lua = b.dependency("treesitter_lua", .{ .target = target, .optimize = optimize });
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "lua", parser_lua.path("."), true, target, optimize));
|
|
||||||
const parser_query = b.dependency("treesitter_query", .{ .target = target, .optimize = optimize });
|
|
||||||
test_deps.dependOn(add_ts_parser(b, "query", parser_query.path("."), false, target, optimize));
|
|
||||||
|
|
||||||
const unit_headers: ?[]const LazyPath = if (support_unittests) &(unittest_include_path ++ .{gen_headers.getDirectory()}) else null;
|
|
||||||
|
|
||||||
try tests.test_steps(b, nvim_exe, test_deps, lua_dev_deps.path("."), test_config_step.getDirectory(), unit_headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn test_fixture(
|
|
||||||
b: *std.Build,
|
|
||||||
name: []const u8,
|
|
||||||
libuv: ?*std.Build.Step.Compile,
|
|
||||||
target: std.Build.ResolvedTarget,
|
|
||||||
optimize: std.builtin.OptimizeMode,
|
|
||||||
) *std.Build.Step {
|
|
||||||
const fixture = b.addExecutable(.{
|
|
||||||
.name = name,
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const source = if (std.mem.eql(u8, name, "pwsh-test")) "shell-test" else name;
|
|
||||||
fixture.addCSourceFile(.{ .file = b.path(b.fmt("./test/functional/fixtures/{s}.c", .{source})) });
|
|
||||||
fixture.linkLibC();
|
|
||||||
if (libuv) |uv| fixture.linkLibrary(uv);
|
|
||||||
return &b.addInstallArtifact(fixture, .{}).step;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_ts_parser(
|
|
||||||
b: *std.Build,
|
|
||||||
name: []const u8,
|
|
||||||
parser_dir: LazyPath,
|
|
||||||
scanner: bool,
|
|
||||||
target: std.Build.ResolvedTarget,
|
|
||||||
optimize: std.builtin.OptimizeMode,
|
|
||||||
) *std.Build.Step {
|
|
||||||
const parser = b.addLibrary(.{
|
|
||||||
.name = name,
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
}),
|
|
||||||
.linkage = .dynamic,
|
|
||||||
});
|
|
||||||
parser.addCSourceFile(.{ .file = parser_dir.path(b, "src/parser.c") });
|
|
||||||
if (scanner) parser.addCSourceFile(.{ .file = parser_dir.path(b, "src/scanner.c") });
|
|
||||||
parser.addIncludePath(parser_dir.path(b, "src"));
|
|
||||||
parser.linkLibC();
|
|
||||||
|
|
||||||
const parser_install = b.addInstallArtifact(parser, .{ .dest_sub_path = b.fmt("parser/{s}.so", .{name}) });
|
|
||||||
return &parser_install.step;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn lua_version_info(b: *std.Build) []u8 {
|
|
||||||
const v = version;
|
|
||||||
return b.fmt(
|
|
||||||
\\return {{
|
|
||||||
\\ {{"major", {}}},
|
|
||||||
\\ {{"minor", {}}},
|
|
||||||
\\ {{"patch", {}}},
|
|
||||||
\\ {{"prerelease", {}}},
|
|
||||||
\\ {{"api_level", {}}},
|
|
||||||
\\ {{"api_compatible", {}}},
|
|
||||||
\\ {{"api_prerelease", {}}},
|
|
||||||
\\}}
|
|
||||||
, .{ v.major, v.minor, v.patch, v.prerelease.len > 0, v.api_level, v.api_level_compat, v.api_prerelease });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn test_config(b: *std.Build) ![]u8 {
|
|
||||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
|
||||||
const src_path = try b.build_root.handle.realpath(".", &buf);
|
|
||||||
|
|
||||||
// we don't use test/cmakeconfig/paths.lua.in because it contains cmake specific logic
|
|
||||||
return b.fmt(
|
|
||||||
\\local M = {{}}
|
|
||||||
\\
|
|
||||||
\\M.apple_sysroot = ""
|
|
||||||
\\M.translations_enabled = "$ENABLE_TRANSLATIONS" == "ON"
|
|
||||||
\\M.is_asan = "$ENABLE_ASAN_UBSAN" == "ON"
|
|
||||||
\\M.is_zig_build = true
|
|
||||||
\\M.vterm_test_file = "test/vterm_test_output"
|
|
||||||
\\M.test_build_dir = "{[bin_dir]s}" -- bull
|
|
||||||
\\M.test_source_path = "{[src_path]s}"
|
|
||||||
\\M.test_lua_prg = ""
|
|
||||||
\\M.test_luajit_prg = ""
|
|
||||||
\\ -- include path passed on the cmdline, see test/lua_runner.lua
|
|
||||||
\\M.include_paths = _G.c_include_path or {{}}
|
|
||||||
\\
|
|
||||||
\\return M
|
|
||||||
, .{ .bin_dir = b.install_path, .src_path = src_path });
|
|
||||||
}
|
|
@@ -1,72 +0,0 @@
|
|||||||
.{
|
|
||||||
.name = .neovim,
|
|
||||||
.fingerprint = 0x66eb090879307a38,
|
|
||||||
.version = "0.12.0",
|
|
||||||
.minimum_zig_version = "0.14.0",
|
|
||||||
|
|
||||||
.dependencies = .{
|
|
||||||
.zlua = .{
|
|
||||||
.url = "git+https://github.com/natecraddock/ziglua#6889b2d90ee6ae96810a9f04ec7c62d9aa91d088",
|
|
||||||
.hash = "zlua-0.1.0-hGRpCxctBQDEQgDArJ0Kc4RDIsD-Hw3pw9pPPw_kGmmY",
|
|
||||||
},
|
|
||||||
.lpeg = .{
|
|
||||||
.url = "https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz",
|
|
||||||
.hash = "N-V-__8AAMnaAwCEutreuREG3QayBVEZqUTDQFY1Nsrv2OIt",
|
|
||||||
},
|
|
||||||
.luv = .{
|
|
||||||
.url = "git+https://github.com/luvit/luv?ref=1.51.0-1#4c9fbc6cf6f3338bb0e0426710cf885ee557b540",
|
|
||||||
.hash = "N-V-__8AAMlNDwCY07jUoMiq3iORXdZy0uFWKiHsy8MaDBJA",
|
|
||||||
},
|
|
||||||
.lua_compat53 = .{
|
|
||||||
.url = "https://github.com/lunarmodules/lua-compat-5.3/archive/v0.13.tar.gz",
|
|
||||||
.hash = "N-V-__8AADi-AwDnVoXwDCQvv2wcYOmN0bJLqZ44J3lwoQY2",
|
|
||||||
},
|
|
||||||
.treesitter = .{
|
|
||||||
.url = "git+https://github.com/tree-sitter/tree-sitter#d87921bb9c39b0b06c811f2082f9a9991cdca027",
|
|
||||||
.hash = "tree_sitter-0.26.0-Tw2sRxO7CwC0NyDrSygSi7UXRHMNUFEF8GRq6dK81lRF",
|
|
||||||
},
|
|
||||||
.libuv = .{
|
|
||||||
.url = "git+https://github.com/allyourcodebase/libuv#a2dfd385bd2a00d6d290fda85a40a55a9d6cffc5",
|
|
||||||
.hash = "libuv-1.51.0-htqqv6liAADxBLIBCZT-qUh_3nRRwtNYsOFQOUmrd_sx",
|
|
||||||
},
|
|
||||||
.utf8proc = .{ .path = "./deps/utf8proc/" },
|
|
||||||
.unibilium = .{ .path = "./deps/unibilium/" },
|
|
||||||
.libiconv = .{
|
|
||||||
.url = "git+https://github.com/allyourcodebase/libiconv#9def4c8a1743380e85bcedb80f2c15b455e236f3",
|
|
||||||
.hash = "libiconv-1.18.0-p9sJwWnqAACzVYeWgXB5r5lOQ74XwTPlptixV0JPRO28",
|
|
||||||
.lazy = true,
|
|
||||||
},
|
|
||||||
.lua_dev_deps = .{
|
|
||||||
.url = "https://github.com/neovim/deps/raw/06ef2b58b0876f8de1a3f5a710473dcd7afff251/opt/lua-dev-deps.tar.gz",
|
|
||||||
.hash = "N-V-__8AAGevEQCHAkCozca5AIdN9DFc3Luf3g3r2AcbyOrm",
|
|
||||||
},
|
|
||||||
.treesitter_c = .{
|
|
||||||
.url = "git+https://github.com/tree-sitter/tree-sitter-c?ref=v0.24.1#7fa1be1b694b6e763686793d97da01f36a0e5c12",
|
|
||||||
.hash = "N-V-__8AANxPSABzw3WBTSH_YkwaGAfrK6PBqAMqQedkDDim",
|
|
||||||
},
|
|
||||||
.treesitter_markdown = .{
|
|
||||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-markdown?ref=v0.5.0#afaa4138517363362f54c89330c9d79391e81168",
|
|
||||||
.hash = "N-V-__8AAIIZUwD3CGdyI2DiHu7Suj2jIF_EAVlM6REFGwju",
|
|
||||||
},
|
|
||||||
.treesitter_lua = .{
|
|
||||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-lua?ref=v0.4.0#4569d1c361129e71a205b94a05e158bd71b1709f",
|
|
||||||
.hash = "N-V-__8AAEF5CABqSL9zqc03aQsT6Nni54ZCcL98pnuDL2D3",
|
|
||||||
},
|
|
||||||
.treesitter_vim = .{
|
|
||||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-vim?ref=v0.7.0#3dd4747082d1b717b8978211c06ef7b6cd16125b",
|
|
||||||
.hash = "N-V-__8AAMArVAB4uo2wg2XRs8HBviQ4Pq366cC_iRolX4Vc",
|
|
||||||
},
|
|
||||||
.treesitter_vimdoc = .{
|
|
||||||
.url = "git+https://github.com/neovim/tree-sitter-vimdoc?ref=v4.0.0#9f6191a98702edc1084245abd5523279d4b681fb",
|
|
||||||
.hash = "N-V-__8AAI4YCgD7OqxCEAmz2RqT_ohl6eA4F0fGMtLIe7nb",
|
|
||||||
},
|
|
||||||
.treesitter_query = .{
|
|
||||||
.url = "git+https://github.com/tree-sitter-grammars/tree-sitter-query?ref=v0.6.2#8a43889f89fd0667289936341bff3a77bafade17",
|
|
||||||
.hash = "N-V-__8AAARLBACBLGiXGFTijEzLv8AwiqT_kJpmVjir1BgX",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.paths = .{
|
|
||||||
// TODO(bfredl): explicitly list the subdirs which actually are used
|
|
||||||
"",
|
|
||||||
},
|
|
||||||
}
|
|
@@ -12,10 +12,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NVIM_VERSION_CFLAGS "${VERSION_STRING}"
|
#define NVIM_VERSION_CFLAGS "${VERSION_STRING}"
|
||||||
#ifdef ZIG_BUILD
|
#define NVIM_VERSION_BUILD_TYPE "$<CONFIG>"
|
||||||
# define NVIM_VERSION_BUILD_TYPE "${CONFIG}"
|
|
||||||
#else
|
|
||||||
# define NVIM_VERSION_BUILD_TYPE "$<CONFIG>"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // AUTO_VERSIONDEF_H
|
#endif // AUTO_VERSIONDEF_H
|
||||||
|
@@ -73,7 +73,7 @@ if(HAS_OG_FLAG)
|
|||||||
set(DEFAULT_MAKE_CFLAGS CFLAGS+=-Og ${DEFAULT_MAKE_CFLAGS})
|
set(DEFAULT_MAKE_CFLAGS CFLAGS+=-Og ${DEFAULT_MAKE_CFLAGS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(DEPS_INCLUDE_FLAGS "-I\"${DEPS_INSTALL_DIR}/include\" -I\"${DEPS_INSTALL_DIR}/include/luajit-2.1\"")
|
set(DEPS_INCLUDE_FLAGS "-I${DEPS_INSTALL_DIR}/include -I${DEPS_INSTALL_DIR}/include/luajit-2.1")
|
||||||
|
|
||||||
# If the macOS deployment target is not set manually (via $MACOSX_DEPLOYMENT_TARGET),
|
# If the macOS deployment target is not set manually (via $MACOSX_DEPLOYMENT_TARGET),
|
||||||
# fall back to local system version. Needs to be done here and in top-level CMakeLists.txt.
|
# fall back to local system version. Needs to be done here and in top-level CMakeLists.txt.
|
||||||
@@ -96,10 +96,10 @@ else()
|
|||||||
find_package(Lua 5.1 EXACT)
|
find_package(Lua 5.1 EXACT)
|
||||||
if(LUAJIT_FOUND)
|
if(LUAJIT_FOUND)
|
||||||
set(LUA_ENGINE LuaJit)
|
set(LUA_ENGINE LuaJit)
|
||||||
string(APPEND DEPS_INCLUDE_FLAGS " -I\"${LUAJIT_INCLUDE_DIR}\"")
|
string(APPEND DEPS_INCLUDE_FLAGS " -I${LUAJIT_INCLUDE_DIR}")
|
||||||
elseif(LUA_FOUND)
|
elseif(LUA_FOUND)
|
||||||
set(LUA_ENGINE Lua)
|
set(LUA_ENGINE Lua)
|
||||||
string(APPEND DEPS_INCLUDE_FLAGS " -I\"${LUA_INCLUDE_DIR}\"")
|
string(APPEND DEPS_INCLUDE_FLAGS " -I${LUA_INCLUDE_DIR}")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Could not find system lua or luajit")
|
message(FATAL_ERROR "Could not find system lua or luajit")
|
||||||
endif()
|
endif()
|
||||||
|
@@ -42,7 +42,7 @@ if(APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
BuildLuajit(INSTALL_COMMAND ${BUILDCMD_UNIX}
|
BuildLuaJit(INSTALL_COMMAND ${BUILDCMD_UNIX}
|
||||||
CC=${DEPS_C_COMPILER} PREFIX=${DEPS_INSTALL_DIR}
|
CC=${DEPS_C_COMPILER} PREFIX=${DEPS_INSTALL_DIR}
|
||||||
${DEPLOYMENT_TARGET} install)
|
${DEPLOYMENT_TARGET} install)
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ elseif(MINGW)
|
|||||||
else()
|
else()
|
||||||
set(LUAJIT_MAKE_PRG ${CMAKE_MAKE_PROGRAM})
|
set(LUAJIT_MAKE_PRG ${CMAKE_MAKE_PROGRAM})
|
||||||
endif()
|
endif()
|
||||||
BuildLuajit(BUILD_COMMAND ${LUAJIT_MAKE_PRG} CC=${DEPS_C_COMPILER}
|
BuildLuaJit(BUILD_COMMAND ${LUAJIT_MAKE_PRG} CC=${DEPS_C_COMPILER}
|
||||||
PREFIX=${DEPS_INSTALL_DIR}
|
PREFIX=${DEPS_INSTALL_DIR}
|
||||||
CFLAGS+=-DLUA_USE_APICHECK
|
CFLAGS+=-DLUA_USE_APICHECK
|
||||||
CFLAGS+=-funwind-tables
|
CFLAGS+=-funwind-tables
|
||||||
@@ -75,7 +75,7 @@ elseif(MINGW)
|
|||||||
)
|
)
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
|
|
||||||
BuildLuajit(
|
BuildLuaJit(
|
||||||
BUILD_COMMAND ${CMAKE_COMMAND} -E chdir ${DEPS_BUILD_DIR}/src/luajit/src ${DEPS_BUILD_DIR}/src/luajit/src/msvcbuild.bat
|
BUILD_COMMAND ${CMAKE_COMMAND} -E chdir ${DEPS_BUILD_DIR}/src/luajit/src ${DEPS_BUILD_DIR}/src/luajit/src/msvcbuild.bat
|
||||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}
|
INSTALL_COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPS_BIN_DIR}
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/luajit.exe ${DEPS_BIN_DIR}
|
COMMAND ${CMAKE_COMMAND} -E copy ${DEPS_BUILD_DIR}/src/luajit/src/luajit.exe ${DEPS_BIN_DIR}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
LIBUV_URL https://github.com/libuv/libuv/archive/v1.51.0.tar.gz
|
LIBUV_URL https://github.com/libuv/libuv/archive/v1.50.0.tar.gz
|
||||||
LIBUV_SHA256 27e55cf7083913bfb6826ca78cde9de7647cded648d35f24163f2d31bb9f51cd
|
LIBUV_SHA256 b1ec56444ee3f1e10c8bd3eed16ba47016ed0b94fe42137435aaf2e0bd574579
|
||||||
|
|
||||||
LUAJIT_URL https://github.com/luajit/luajit/archive/871db2c84ecefd70a850e03a6c340214a81739f0.tar.gz
|
LUAJIT_URL https://github.com/luajit/luajit/archive/538a82133ad6fddfd0ca64de167c4aca3bc1a2da.tar.gz
|
||||||
LUAJIT_SHA256 ab3f16d82df6946543565cfb0d2810d387d79a3a43e0431695b03466188e2680
|
LUAJIT_SHA256 7acbc36be8f21072422eb9a5e5fc468d0eaa55bec1b70260d651e845684621e2
|
||||||
|
|
||||||
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
|
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
|
||||||
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
||||||
@@ -10,8 +10,8 @@ LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
|
|||||||
UNIBILIUM_URL https://github.com/neovim/unibilium/archive/v2.1.2.tar.gz
|
UNIBILIUM_URL https://github.com/neovim/unibilium/archive/v2.1.2.tar.gz
|
||||||
UNIBILIUM_SHA256 370ecb07fbbc20d91d1b350c55f1c806b06bf86797e164081ccc977fc9b3af7a
|
UNIBILIUM_SHA256 370ecb07fbbc20d91d1b350c55f1c806b06bf86797e164081ccc977fc9b3af7a
|
||||||
|
|
||||||
LUV_URL https://github.com/luvit/luv/archive/1.51.0-1.tar.gz
|
LUV_URL https://github.com/luvit/luv/archive/1.50.0-1.tar.gz
|
||||||
LUV_SHA256 d4a11178ae8e16ba5886799ea91905dd9b0b479c75aebd67866d37373e41526f
|
LUV_SHA256 bb4f0570571e40c1d2a7644f6f9c1309a6ccdb19bf4d397e8d7bfd0c6b88e613
|
||||||
|
|
||||||
LPEG_URL https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz
|
LPEG_URL https://github.com/neovim/deps/raw/d495ee6f79e7962a53ad79670cb92488abe0b9b4/opt/lpeg-1.1.0.tar.gz
|
||||||
LPEG_SHA256 4b155d67d2246c1ffa7ad7bc466c1ea899bbc40fef0257cc9c03cecbaed4352a
|
LPEG_SHA256 4b155d67d2246c1ffa7ad7bc466c1ea899bbc40fef0257cc9c03cecbaed4352a
|
||||||
@@ -46,13 +46,13 @@ TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/a
|
|||||||
TREESITTER_QUERY_SHA256 90682e128d048fbf2a2a17edca947db71e326fa0b3dba4136e041e096538b4eb
|
TREESITTER_QUERY_SHA256 90682e128d048fbf2a2a17edca947db71e326fa0b3dba4136e041e096538b4eb
|
||||||
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.5.0.tar.gz
|
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.5.0.tar.gz
|
||||||
TREESITTER_MARKDOWN_SHA256 14c2c948ccf0e9b606eec39b09286c59dddf28307849f71b7ce2b1d1ef06937e
|
TREESITTER_MARKDOWN_SHA256 14c2c948ccf0e9b606eec39b09286c59dddf28307849f71b7ce2b1d1ef06937e
|
||||||
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.25.8.tar.gz
|
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.25.6.tar.gz
|
||||||
TREESITTER_SHA256 178b575244d967f4920a4642408dc4edf6de96948d37d7f06e5b78acee9c0b4e
|
TREESITTER_SHA256 ac6ed919c6d849e8553e246d5cd3fa22661f6c7b6497299264af433f3629957c
|
||||||
|
|
||||||
WASMTIME_URL https://github.com/bytecodealliance/wasmtime/archive/v29.0.1.tar.gz
|
WASMTIME_URL https://github.com/bytecodealliance/wasmtime/archive/v29.0.1.tar.gz
|
||||||
WASMTIME_SHA256 b94b6c6fd6aebaf05d4c69c1b12b5dc217b0d42c1a95f435b33af63dddfa5304
|
WASMTIME_SHA256 b94b6c6fd6aebaf05d4c69c1b12b5dc217b0d42c1a95f435b33af63dddfa5304
|
||||||
|
|
||||||
UNCRUSTIFY_URL https://github.com/uncrustify/uncrustify/archive/uncrustify-0.81.0.tar.gz
|
UNCRUSTIFY_URL https://github.com/uncrustify/uncrustify/archive/uncrustify-0.80.1.tar.gz
|
||||||
UNCRUSTIFY_SHA256 484623dc16b92206adc6ac0770077c6c67c6e441102148c2a121a19549330ff9
|
UNCRUSTIFY_SHA256 0e2616ec2f78e12816388c513f7060072ff7942b42f1175eb28b24cb75aaec48
|
||||||
LUA_DEV_DEPS_URL https://github.com/neovim/deps/raw/06ef2b58b0876f8de1a3f5a710473dcd7afff251/opt/lua-dev-deps.tar.gz
|
LUA_DEV_DEPS_URL https://github.com/neovim/deps/raw/06ef2b58b0876f8de1a3f5a710473dcd7afff251/opt/lua-dev-deps.tar.gz
|
||||||
LUA_DEV_DEPS_SHA256 49f8399e453103064a23c65534f266f3067cda716b6502f016bfafeed5799354
|
LUA_DEV_DEPS_SHA256 49f8399e453103064a23c65534f266f3067cda716b6502f016bfafeed5799354
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|ARM64|aarch64)$")
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||||
set(CMAKE_SYSTEM_PROCESSOR arm64)
|
set(CMAKE_SYSTEM_PROCESSOR arm64)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -27,13 +27,9 @@ set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md)
|
|||||||
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
|
set(CPACK_PACKAGE_FILE_NAME "nvim-win64")
|
||||||
set(CPACK_PACKAGE_FILE_NAME "nvim-win-arm64")
|
|
||||||
else()
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME "nvim-win64")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CPACK_GENERATOR ZIP WIX)
|
set(CPACK_GENERATOR ZIP WIX)
|
||||||
|
|
||||||
# WIX
|
# WIX
|
||||||
# CPACK_WIX_UPGRADE_GUID should be set, but should never change.
|
# CPACK_WIX_UPGRADE_GUID should be set, but should never change.
|
||||||
# CPACK_WIX_PRODUCT_GUID should not be set (leave as default to auto-generate).
|
# CPACK_WIX_PRODUCT_GUID should not be set (leave as default to auto-generate).
|
||||||
|
@@ -7,7 +7,6 @@ set(ENV{XDG_DATA_HOME} ${BUILD_DIR}/Xtest_xdg/share)
|
|||||||
set(ENV{XDG_STATE_HOME} ${BUILD_DIR}/Xtest_xdg/state)
|
set(ENV{XDG_STATE_HOME} ${BUILD_DIR}/Xtest_xdg/state)
|
||||||
unset(ENV{XDG_DATA_DIRS})
|
unset(ENV{XDG_DATA_DIRS})
|
||||||
unset(ENV{NVIM}) # Clear $NVIM in case tests are running from Nvim. #11009
|
unset(ENV{NVIM}) # Clear $NVIM in case tests are running from Nvim. #11009
|
||||||
unset(ENV{TMUX}) # Nvim TUI shouldn't think it's running in tmux. #34173
|
|
||||||
|
|
||||||
# TODO(dundargoc): The CIRRUS_CI environment variable isn't passed to here from
|
# TODO(dundargoc): The CIRRUS_CI environment variable isn't passed to here from
|
||||||
# the main CMakeLists.txt, so we have to manually pass it to this script and
|
# the main CMakeLists.txt, so we have to manually pass it to this script and
|
||||||
@@ -69,7 +68,7 @@ endif()
|
|||||||
execute_process(
|
execute_process(
|
||||||
# Note: because of "-ll" (low-level interpreter mode), some modules like
|
# Note: because of "-ll" (low-level interpreter mode), some modules like
|
||||||
# _editor.lua are not loaded.
|
# _editor.lua are not loaded.
|
||||||
COMMAND ${NVIM_PRG} -ll ${WORKING_DIR}/test/lua_runner.lua ${DEPS_INSTALL_DIR}/share/lua/5.1/ busted -v -o test.busted.outputHandlers.nvim
|
COMMAND ${NVIM_PRG} -ll ${WORKING_DIR}/test/lua_runner.lua ${DEPS_INSTALL_DIR} busted -v -o test.busted.outputHandlers.nvim
|
||||||
--lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua
|
--lazy --helper=${TEST_DIR}/${TEST_TYPE}/preload.lua
|
||||||
--lpath=${BUILD_DIR}/?.lua
|
--lpath=${BUILD_DIR}/?.lua
|
||||||
--lpath=${WORKING_DIR}/src/?.lua
|
--lpath=${WORKING_DIR}/src/?.lua
|
||||||
@@ -79,6 +78,7 @@ execute_process(
|
|||||||
${TEST_PATH}
|
${TEST_PATH}
|
||||||
TIMEOUT $ENV{TEST_TIMEOUT}
|
TIMEOUT $ENV{TEST_TIMEOUT}
|
||||||
WORKING_DIRECTORY ${WORKING_DIR}
|
WORKING_DIRECTORY ${WORKING_DIR}
|
||||||
|
ERROR_VARIABLE err
|
||||||
RESULT_VARIABLE res
|
RESULT_VARIABLE res
|
||||||
${EXTRA_ARGS})
|
${EXTRA_ARGS})
|
||||||
|
|
||||||
@@ -87,6 +87,11 @@ file(REMOVE_RECURSE ${RM_FILES})
|
|||||||
|
|
||||||
if(res)
|
if(res)
|
||||||
message(STATUS "Tests exited non-zero: ${res}")
|
message(STATUS "Tests exited non-zero: ${res}")
|
||||||
|
if("${err}" STREQUAL "")
|
||||||
|
message(STATUS "No output to stderr.")
|
||||||
|
else()
|
||||||
|
message(STATUS "Output to stderr:\n${err}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Dump the logfile on CI (if not displayed and moved already).
|
# Dump the logfile on CI (if not displayed and moved already).
|
||||||
if(CI_BUILD)
|
if(CI_BUILD)
|
||||||
|
30
deps/unibilium/build.zig
vendored
30
deps/unibilium/build.zig
vendored
@@ -1,30 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const upstream = b.dependency("unibilium", .{});
|
|
||||||
const lib = b.addLibrary(.{
|
|
||||||
.name = "unibilium",
|
|
||||||
.linkage = .static,
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
lib.addIncludePath(upstream.path(""));
|
|
||||||
|
|
||||||
lib.installHeader(upstream.path("unibilium.h"), "unibilium.h");
|
|
||||||
|
|
||||||
lib.linkLibC();
|
|
||||||
|
|
||||||
lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{
|
|
||||||
"unibilium.c",
|
|
||||||
"uninames.c",
|
|
||||||
"uniutil.c",
|
|
||||||
}, .flags = &.{"-DTERMINFO_DIRS=\"/etc/terminfo:/usr/share/terminfo\""} });
|
|
||||||
|
|
||||||
b.installArtifact(lib);
|
|
||||||
}
|
|
12
deps/unibilium/build.zig.zon
vendored
12
deps/unibilium/build.zig.zon
vendored
@@ -1,12 +0,0 @@
|
|||||||
.{
|
|
||||||
.name = "unibilium",
|
|
||||||
.version = "2.1.2",
|
|
||||||
.paths = .{""},
|
|
||||||
|
|
||||||
.dependencies = .{
|
|
||||||
.unibilium = .{
|
|
||||||
.url = "git+https://github.com/neovim/unibilium?ref=v2.1.2#bfcb0350129dd76893bc90399cf37c45812268a2",
|
|
||||||
.hash = "N-V-__8AADO1CgCggvx73yptnBlXbEm7TjOSO6VGIqc0CvYR",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
27
deps/utf8proc/build.zig
vendored
27
deps/utf8proc/build.zig
vendored
@@ -1,27 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const upstream = b.dependency("utf8proc", .{});
|
|
||||||
const lib = b.addLibrary(.{
|
|
||||||
.name = "utf8proc",
|
|
||||||
.linkage = .static,
|
|
||||||
.root_module = b.createModule(.{
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
lib.addIncludePath(upstream.path(""));
|
|
||||||
lib.installHeader(upstream.path("utf8proc.h"), "utf8proc.h");
|
|
||||||
|
|
||||||
lib.linkLibC();
|
|
||||||
|
|
||||||
lib.addCSourceFiles(.{ .root = upstream.path(""), .files = &.{
|
|
||||||
"utf8proc.c",
|
|
||||||
}, .flags = &.{"-DUTF8PROC_STATIC"} });
|
|
||||||
|
|
||||||
b.installArtifact(lib);
|
|
||||||
}
|
|
12
deps/utf8proc/build.zig.zon
vendored
12
deps/utf8proc/build.zig.zon
vendored
@@ -1,12 +0,0 @@
|
|||||||
.{
|
|
||||||
.name = "utf8proc",
|
|
||||||
.version = "2.10.0",
|
|
||||||
.paths = .{""},
|
|
||||||
|
|
||||||
.dependencies = .{
|
|
||||||
.utf8proc = .{
|
|
||||||
.url = "git+https://github.com/JuliaStrings/utf8proc?ref=v2.10.0#a1b99daa2a3393884220264c927a48ba1251a9c6",
|
|
||||||
.hash = "N-V-__8AAPJfKADYDOC95xuKyudrlob6eFqgzfFl8NbpOoU9",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@@ -12,17 +12,12 @@ get_directory_property(LUA_GEN_DEPS DIRECTORY ${PROJECT_SOURCE_DIR}/src/nvim DEF
|
|||||||
|
|
||||||
add_custom_command(OUTPUT ${GENERATED_SYN_VIM}
|
add_custom_command(OUTPUT ${GENERATED_SYN_VIM}
|
||||||
COMMAND ${LUA_GEN} ${SYN_VIM_GENERATOR} ${GENERATED_SYN_VIM} ${FUNCS_DATA}
|
COMMAND ${LUA_GEN} ${SYN_VIM_GENERATOR} ${GENERATED_SYN_VIM} ${FUNCS_DATA}
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/options.lua
|
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua
|
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua
|
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/vvars.lua
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${LUA_GEN_DEPS}
|
${LUA_GEN_DEPS}
|
||||||
${SYN_VIM_GENERATOR}
|
${SYN_VIM_GENERATOR}
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua
|
${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua
|
${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/options.lua
|
${PROJECT_SOURCE_DIR}/src/nvim/options.lua
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/vvars.lua
|
|
||||||
${PROJECT_SOURCE_DIR}/src/nvim/eval.c
|
${PROJECT_SOURCE_DIR}/src/nvim/eval.c
|
||||||
${FUNCS_DATA}
|
${FUNCS_DATA}
|
||||||
)
|
)
|
||||||
|
859
runtime/autoload/ccomplete.lua
Normal file
859
runtime/autoload/ccomplete.lua
Normal file
@@ -0,0 +1,859 @@
|
|||||||
|
----------------------------------------
|
||||||
|
-- This file is generated via github.com/tjdevries/vim9jit
|
||||||
|
-- For any bugs, please first consider reporting there.
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
-- Ignore "value assigned to a local variable is unused" because
|
||||||
|
-- we can't guarantee that local variables will be used by plugins
|
||||||
|
-- luacheck: ignore
|
||||||
|
--- @diagnostic disable
|
||||||
|
|
||||||
|
local vim9 = require('_vim9script')
|
||||||
|
local M = {}
|
||||||
|
local prepended = nil
|
||||||
|
local grepCache = nil
|
||||||
|
local Complete = nil
|
||||||
|
local GetAddition = nil
|
||||||
|
local Tag2item = nil
|
||||||
|
local Dict2info = nil
|
||||||
|
local ParseTagline = nil
|
||||||
|
local Tagline2item = nil
|
||||||
|
local Tagcmd2extra = nil
|
||||||
|
local Nextitem = nil
|
||||||
|
local StructMembers = nil
|
||||||
|
local SearchMembers = nil
|
||||||
|
-- vim9script
|
||||||
|
|
||||||
|
-- # Vim completion script
|
||||||
|
-- # Language: C
|
||||||
|
-- # Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||||
|
-- # Last Change: 2023 Aug 10
|
||||||
|
-- # Rewritten in Vim9 script by github user lacygoill
|
||||||
|
-- # Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
|
|
||||||
|
prepended = ''
|
||||||
|
grepCache = vim.empty_dict()
|
||||||
|
|
||||||
|
-- # This function is used for the 'omnifunc' option.
|
||||||
|
|
||||||
|
Complete = function(findstart, abase)
|
||||||
|
findstart = vim9.bool(findstart)
|
||||||
|
if vim9.bool(findstart) then
|
||||||
|
-- # Locate the start of the item, including ".", "->" and "[...]".
|
||||||
|
local line = vim9.fn.getline('.')
|
||||||
|
local start = vim9.fn.charcol('.') - 1
|
||||||
|
local lastword = -1
|
||||||
|
while start > 0 do
|
||||||
|
if vim9.ops.RegexpMatches(vim9.index(line, vim9.ops.Minus(start, 1)), '\\w') then
|
||||||
|
start = start - 1
|
||||||
|
elseif
|
||||||
|
vim9.bool(vim9.ops.RegexpMatches(vim9.index(line, vim9.ops.Minus(start, 1)), '\\.'))
|
||||||
|
then
|
||||||
|
if lastword == -1 then
|
||||||
|
lastword = start
|
||||||
|
end
|
||||||
|
start = start - 1
|
||||||
|
elseif
|
||||||
|
vim9.bool(
|
||||||
|
start > 1
|
||||||
|
and vim9.index(line, vim9.ops.Minus(start, 2)) == '-'
|
||||||
|
and vim9.index(line, vim9.ops.Minus(start, 1)) == '>'
|
||||||
|
)
|
||||||
|
then
|
||||||
|
if lastword == -1 then
|
||||||
|
lastword = start
|
||||||
|
end
|
||||||
|
start = vim9.ops.Minus(start, 2)
|
||||||
|
elseif vim9.bool(vim9.index(line, vim9.ops.Minus(start, 1)) == ']') then
|
||||||
|
-- # Skip over [...].
|
||||||
|
local n = 0
|
||||||
|
start = start - 1
|
||||||
|
while start > 0 do
|
||||||
|
start = start - 1
|
||||||
|
if vim9.index(line, start) == '[' then
|
||||||
|
if n == 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
n = n - 1
|
||||||
|
elseif vim9.bool(vim9.index(line, start) == ']') then
|
||||||
|
n = n + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Return the column of the last word, which is going to be changed.
|
||||||
|
-- # Remember the text that comes before it in prepended.
|
||||||
|
if lastword == -1 then
|
||||||
|
prepended = ''
|
||||||
|
return vim9.fn.byteidx(line, start)
|
||||||
|
end
|
||||||
|
prepended = vim9.slice(line, start, vim9.ops.Minus(lastword, 1))
|
||||||
|
return vim9.fn.byteidx(line, lastword)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Return list of matches.
|
||||||
|
|
||||||
|
local base = prepended .. abase
|
||||||
|
|
||||||
|
-- # Don't do anything for an empty base, would result in all the tags in the
|
||||||
|
-- # tags file.
|
||||||
|
if base == '' then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # init cache for vimgrep to empty
|
||||||
|
grepCache = {}
|
||||||
|
|
||||||
|
-- # Split item in words, keep empty word after "." or "->".
|
||||||
|
-- # "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc.
|
||||||
|
-- # We can't use split, because we need to skip nested [...].
|
||||||
|
-- # "aa[...]" -> ['aa', '[...]'], "aa.bb[...]" -> ['aa', 'bb', '[...]'], etc.
|
||||||
|
local items = {}
|
||||||
|
local s = 0
|
||||||
|
local arrays = 0
|
||||||
|
while 1 do
|
||||||
|
local e = vim9.fn.charidx(base, vim9.fn.match(base, '\\.\\|->\\|\\[', s))
|
||||||
|
if e < 0 then
|
||||||
|
if s == 0 or vim9.index(base, vim9.ops.Minus(s, 1)) ~= ']' then
|
||||||
|
vim9.fn.add(items, vim9.slice(base, s, nil))
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if s == 0 or vim9.index(base, vim9.ops.Minus(s, 1)) ~= ']' then
|
||||||
|
vim9.fn.add(items, vim9.slice(base, s, vim9.ops.Minus(e, 1)))
|
||||||
|
end
|
||||||
|
if vim9.index(base, e) == '.' then
|
||||||
|
-- # skip over '.'
|
||||||
|
s = vim9.ops.Plus(e, 1)
|
||||||
|
elseif vim9.bool(vim9.index(base, e) == '-') then
|
||||||
|
-- # skip over '->'
|
||||||
|
s = vim9.ops.Plus(e, 2)
|
||||||
|
else
|
||||||
|
-- # Skip over [...].
|
||||||
|
local n = 0
|
||||||
|
s = e
|
||||||
|
e = e + 1
|
||||||
|
while e < vim9.fn.strcharlen(base) do
|
||||||
|
if vim9.index(base, e) == ']' then
|
||||||
|
if n == 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
n = n - 1
|
||||||
|
elseif vim9.bool(vim9.index(base, e) == '[') then
|
||||||
|
n = n + 1
|
||||||
|
end
|
||||||
|
e = e + 1
|
||||||
|
end
|
||||||
|
e = e + 1
|
||||||
|
vim9.fn.add(items, vim9.slice(base, s, vim9.ops.Minus(e, 1)))
|
||||||
|
arrays = arrays + 1
|
||||||
|
s = e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Find the variable items[0].
|
||||||
|
-- # 1. in current function (like with "gd")
|
||||||
|
-- # 2. in tags file(s) (like with ":tag")
|
||||||
|
-- # 3. in current file (like with "gD")
|
||||||
|
local res = {}
|
||||||
|
if vim9.fn.searchdecl(vim9.index(items, 0), false, true) == 0 then
|
||||||
|
-- # Found, now figure out the type.
|
||||||
|
-- # TODO: join previous line if it makes sense
|
||||||
|
local line = vim9.fn.getline('.')
|
||||||
|
local col = vim9.fn.charcol('.')
|
||||||
|
if vim9.fn.stridx(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), ';') >= 0 then
|
||||||
|
-- # Handle multiple declarations on the same line.
|
||||||
|
local col2 = vim9.ops.Minus(col, 1)
|
||||||
|
while vim9.index(line, col2) ~= ';' do
|
||||||
|
col2 = col2 - 1
|
||||||
|
end
|
||||||
|
line = vim9.slice(line, vim9.ops.Plus(col2, 1), nil)
|
||||||
|
col = vim9.ops.Minus(col, col2)
|
||||||
|
end
|
||||||
|
if vim9.fn.stridx(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), ',') >= 0 then
|
||||||
|
-- # Handle multiple declarations on the same line in a function
|
||||||
|
-- # declaration.
|
||||||
|
local col2 = vim9.ops.Minus(col, 1)
|
||||||
|
while vim9.index(line, col2) ~= ',' do
|
||||||
|
col2 = col2 - 1
|
||||||
|
end
|
||||||
|
if
|
||||||
|
vim9.ops.RegexpMatches(
|
||||||
|
vim9.slice(line, vim9.ops.Plus(col2, 1), vim9.ops.Minus(col, 1)),
|
||||||
|
' *[^ ][^ ]* *[^ ]'
|
||||||
|
)
|
||||||
|
then
|
||||||
|
line = vim9.slice(line, vim9.ops.Plus(col2, 1), nil)
|
||||||
|
col = vim9.ops.Minus(col, col2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if vim9.fn.len(items) == 1 then
|
||||||
|
-- # Completing one word and it's a local variable: May add '[', '.' or
|
||||||
|
-- # '->'.
|
||||||
|
local match = vim9.index(items, 0)
|
||||||
|
local kind = 'v'
|
||||||
|
if vim9.fn.match(line, '\\<' .. match .. '\\s*\\[') > 0 then
|
||||||
|
match = match .. '['
|
||||||
|
else
|
||||||
|
res = Nextitem(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), { '' }, 0, true)
|
||||||
|
if vim9.fn.len(res) > 0 then
|
||||||
|
-- # There are members, thus add "." or "->".
|
||||||
|
if vim9.fn.match(line, '\\*[ \\t(]*' .. match .. '\\>') > 0 then
|
||||||
|
match = match .. '->'
|
||||||
|
else
|
||||||
|
match = match .. '.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
res = { { ['match'] = match, ['tagline'] = '', ['kind'] = kind, ['info'] = line } }
|
||||||
|
elseif vim9.bool(vim9.fn.len(items) == vim9.ops.Plus(arrays, 1)) then
|
||||||
|
-- # Completing one word and it's a local array variable: build tagline
|
||||||
|
-- # from declaration line
|
||||||
|
local match = vim9.index(items, 0)
|
||||||
|
local kind = 'v'
|
||||||
|
local tagline = '\t/^' .. line .. '$/'
|
||||||
|
res = { { ['match'] = match, ['tagline'] = tagline, ['kind'] = kind, ['info'] = line } }
|
||||||
|
else
|
||||||
|
-- # Completing "var.", "var.something", etc.
|
||||||
|
res =
|
||||||
|
Nextitem(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), vim9.slice(items, 1, nil), 0, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.fn.len(items) == 1 or vim9.fn.len(items) == vim9.ops.Plus(arrays, 1) then
|
||||||
|
-- # Only one part, no "." or "->": complete from tags file.
|
||||||
|
local tags = {}
|
||||||
|
if vim9.fn.len(items) == 1 then
|
||||||
|
tags = vim9.fn.taglist('^' .. base)
|
||||||
|
else
|
||||||
|
tags = vim9.fn.taglist('^' .. vim9.index(items, 0) .. '$')
|
||||||
|
end
|
||||||
|
|
||||||
|
vim9.fn_mut('filter', {
|
||||||
|
vim9.fn_mut('filter', {
|
||||||
|
tags,
|
||||||
|
function(_, v)
|
||||||
|
return vim9.ternary(vim9.fn.has_key(v, 'kind'), function()
|
||||||
|
return v.kind ~= 'm'
|
||||||
|
end, true)
|
||||||
|
end,
|
||||||
|
}, { replace = 0 }),
|
||||||
|
function(_, v)
|
||||||
|
return vim9.ops.Or(
|
||||||
|
vim9.ops.Or(
|
||||||
|
vim9.prefix['Bang'](vim9.fn.has_key(v, 'static')),
|
||||||
|
vim9.prefix['Bang'](vim9.index(v, 'static'))
|
||||||
|
),
|
||||||
|
vim9.fn.bufnr('%') == vim9.fn.bufnr(vim9.index(v, 'filename'))
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
}, { replace = 0 })
|
||||||
|
|
||||||
|
res = vim9.fn.extend(
|
||||||
|
res,
|
||||||
|
vim9.fn.map(tags, function(_, v)
|
||||||
|
return Tag2item(v)
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.fn.len(res) == 0 then
|
||||||
|
-- # Find the variable in the tags file(s)
|
||||||
|
local diclist = vim9.fn.filter(
|
||||||
|
vim9.fn.taglist('^' .. vim9.index(items, 0) .. '$'),
|
||||||
|
function(_, v)
|
||||||
|
return vim9.ternary(vim9.fn.has_key(v, 'kind'), function()
|
||||||
|
return v.kind ~= 'm'
|
||||||
|
end, true)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
res = {}
|
||||||
|
|
||||||
|
for _, i in vim9.iter(vim9.fn.range(vim9.fn.len(diclist))) do
|
||||||
|
-- # New ctags has the "typeref" field. Patched version has "typename".
|
||||||
|
if vim9.bool(vim9.fn.has_key(vim9.index(diclist, i), 'typename')) then
|
||||||
|
res = vim9.fn.extend(
|
||||||
|
res,
|
||||||
|
StructMembers(
|
||||||
|
vim9.index(vim9.index(diclist, i), 'typename'),
|
||||||
|
vim9.slice(items, 1, nil),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elseif vim9.bool(vim9.fn.has_key(vim9.index(diclist, i), 'typeref')) then
|
||||||
|
res = vim9.fn.extend(
|
||||||
|
res,
|
||||||
|
StructMembers(
|
||||||
|
vim9.index(vim9.index(diclist, i), 'typeref'),
|
||||||
|
vim9.slice(items, 1, nil),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # For a variable use the command, which must be a search pattern that
|
||||||
|
-- # shows the declaration of the variable.
|
||||||
|
if vim9.index(vim9.index(diclist, i), 'kind') == 'v' then
|
||||||
|
local line = vim9.index(vim9.index(diclist, i), 'cmd')
|
||||||
|
if vim9.slice(line, nil, 1) == '/^' then
|
||||||
|
local col =
|
||||||
|
vim9.fn.charidx(line, vim9.fn.match(line, '\\<' .. vim9.index(items, 0) .. '\\>'))
|
||||||
|
res = vim9.fn.extend(
|
||||||
|
res,
|
||||||
|
Nextitem(
|
||||||
|
vim9.slice(line, 2, vim9.ops.Minus(col, 1)),
|
||||||
|
vim9.slice(items, 1, nil),
|
||||||
|
0,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.fn.len(res) == 0 and vim9.fn.searchdecl(vim9.index(items, 0), true) == 0 then
|
||||||
|
-- # Found, now figure out the type.
|
||||||
|
-- # TODO: join previous line if it makes sense
|
||||||
|
local line = vim9.fn.getline('.')
|
||||||
|
local col = vim9.fn.charcol('.')
|
||||||
|
res =
|
||||||
|
Nextitem(vim9.slice(line, nil, vim9.ops.Minus(col, 1)), vim9.slice(items, 1, nil), 0, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # If the last item(s) are [...] they need to be added to the matches.
|
||||||
|
local last = vim9.fn.len(items) - 1
|
||||||
|
local brackets = ''
|
||||||
|
while last >= 0 do
|
||||||
|
if vim9.index(vim9.index(items, last), 0) ~= '[' then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
brackets = vim9.index(items, last) .. brackets
|
||||||
|
last = last - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim9.fn.map(res, function(_, v)
|
||||||
|
return Tagline2item(v, brackets)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
M['Complete'] = Complete
|
||||||
|
|
||||||
|
GetAddition = function(line, match, memarg, bracket)
|
||||||
|
bracket = vim9.bool(bracket)
|
||||||
|
-- # Guess if the item is an array.
|
||||||
|
if vim9.bool(vim9.ops.And(bracket, vim9.fn.match(line, match .. '\\s*\\[') > 0)) then
|
||||||
|
return '['
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Check if the item has members.
|
||||||
|
if vim9.fn.len(SearchMembers(memarg, { '' }, false)) > 0 then
|
||||||
|
-- # If there is a '*' before the name use "->".
|
||||||
|
if vim9.fn.match(line, '\\*[ \\t(]*' .. match .. '\\>') > 0 then
|
||||||
|
return '->'
|
||||||
|
else
|
||||||
|
return '.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
|
Tag2item = function(val)
|
||||||
|
-- # Turn the tag info "val" into an item for completion.
|
||||||
|
-- # "val" is is an item in the list returned by taglist().
|
||||||
|
-- # If it is a variable we may add "." or "->". Don't do it for other types,
|
||||||
|
-- # such as a typedef, by not including the info that GetAddition() uses.
|
||||||
|
local res = vim9.convert.decl_dict({ ['match'] = vim9.index(val, 'name') })
|
||||||
|
|
||||||
|
res[vim9.index_expr('extra')] =
|
||||||
|
Tagcmd2extra(vim9.index(val, 'cmd'), vim9.index(val, 'name'), vim9.index(val, 'filename'))
|
||||||
|
|
||||||
|
local s = Dict2info(val)
|
||||||
|
if s ~= '' then
|
||||||
|
res[vim9.index_expr('info')] = s
|
||||||
|
end
|
||||||
|
|
||||||
|
res[vim9.index_expr('tagline')] = ''
|
||||||
|
if vim9.bool(vim9.fn.has_key(val, 'kind')) then
|
||||||
|
local kind = vim9.index(val, 'kind')
|
||||||
|
res[vim9.index_expr('kind')] = kind
|
||||||
|
if kind == 'v' then
|
||||||
|
res[vim9.index_expr('tagline')] = '\t' .. vim9.index(val, 'cmd')
|
||||||
|
res[vim9.index_expr('dict')] = val
|
||||||
|
elseif vim9.bool(kind == 'f') then
|
||||||
|
res[vim9.index_expr('match')] = vim9.index(val, 'name') .. '('
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
Dict2info = function(dict)
|
||||||
|
-- # Use all the items in dictionary for the "info" entry.
|
||||||
|
local info = ''
|
||||||
|
|
||||||
|
for _, k in vim9.iter(vim9.fn_mut('sort', { vim9.fn.keys(dict) }, { replace = 0 })) do
|
||||||
|
info = info .. k .. vim9.fn['repeat'](' ', 10 - vim9.fn.strlen(k))
|
||||||
|
if k == 'cmd' then
|
||||||
|
info = info
|
||||||
|
.. vim9.fn.substitute(
|
||||||
|
vim9.fn.matchstr(vim9.index(dict, 'cmd'), '/^\\s*\\zs.*\\ze$/'),
|
||||||
|
'\\\\\\(.\\)',
|
||||||
|
'\\1',
|
||||||
|
'g'
|
||||||
|
)
|
||||||
|
else
|
||||||
|
local dictk = vim9.index(dict, k)
|
||||||
|
if vim9.fn.typename(dictk) ~= 'string' then
|
||||||
|
info = info .. vim9.fn.string(dictk)
|
||||||
|
else
|
||||||
|
info = info .. dictk
|
||||||
|
end
|
||||||
|
end
|
||||||
|
info = info .. '\n'
|
||||||
|
end
|
||||||
|
|
||||||
|
return info
|
||||||
|
end
|
||||||
|
|
||||||
|
ParseTagline = function(line)
|
||||||
|
-- # Parse a tag line and return a dictionary with items like taglist()
|
||||||
|
local l = vim9.fn.split(line, '\t')
|
||||||
|
local d = vim.empty_dict()
|
||||||
|
if vim9.fn.len(l) >= 3 then
|
||||||
|
d[vim9.index_expr('name')] = vim9.index(l, 0)
|
||||||
|
d[vim9.index_expr('filename')] = vim9.index(l, 1)
|
||||||
|
d[vim9.index_expr('cmd')] = vim9.index(l, 2)
|
||||||
|
local n = 2
|
||||||
|
if vim9.ops.RegexpMatches(vim9.index(l, 2), '^/') then
|
||||||
|
-- # Find end of cmd, it may contain Tabs.
|
||||||
|
while n < vim9.fn.len(l) and vim9.ops.NotRegexpMatches(vim9.index(l, n), '/;"$') do
|
||||||
|
n = n + 1
|
||||||
|
d[vim9.index_expr('cmd')] = vim9.index(d, 'cmd') .. ' ' .. vim9.index(l, n)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, i in vim9.iter(vim9.fn.range(vim9.ops.Plus(n, 1), vim9.fn.len(l) - 1)) do
|
||||||
|
if vim9.index(l, i) == 'file:' then
|
||||||
|
d[vim9.index_expr('static')] = 1
|
||||||
|
elseif vim9.bool(vim9.ops.NotRegexpMatches(vim9.index(l, i), ':')) then
|
||||||
|
d[vim9.index_expr('kind')] = vim9.index(l, i)
|
||||||
|
else
|
||||||
|
d[vim9.index_expr(vim9.fn.matchstr(vim9.index(l, i), '[^:]*'))] =
|
||||||
|
vim9.fn.matchstr(vim9.index(l, i), ':\\zs.*')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return d
|
||||||
|
end
|
||||||
|
|
||||||
|
Tagline2item = function(val, brackets)
|
||||||
|
-- # Turn a match item "val" into an item for completion.
|
||||||
|
-- # "val['match']" is the matching item.
|
||||||
|
-- # "val['tagline']" is the tagline in which the last part was found.
|
||||||
|
local line = vim9.index(val, 'tagline')
|
||||||
|
local add = GetAddition(line, vim9.index(val, 'match'), { val }, brackets == '')
|
||||||
|
local res = vim9.convert.decl_dict({ ['word'] = vim9.index(val, 'match') .. brackets .. add })
|
||||||
|
|
||||||
|
if vim9.bool(vim9.fn.has_key(val, 'info')) then
|
||||||
|
-- # Use info from Tag2item().
|
||||||
|
res[vim9.index_expr('info')] = vim9.index(val, 'info')
|
||||||
|
else
|
||||||
|
-- # Parse the tag line and add each part to the "info" entry.
|
||||||
|
local s = Dict2info(ParseTagline(line))
|
||||||
|
if s ~= '' then
|
||||||
|
res[vim9.index_expr('info')] = s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.bool(vim9.fn.has_key(val, 'kind')) then
|
||||||
|
res[vim9.index_expr('kind')] = vim9.index(val, 'kind')
|
||||||
|
elseif vim9.bool(add == '(') then
|
||||||
|
res[vim9.index_expr('kind')] = 'f'
|
||||||
|
else
|
||||||
|
local s = vim9.fn.matchstr(line, '\\t\\(kind:\\)\\=\\zs\\S\\ze\\(\\t\\|$\\)')
|
||||||
|
if s ~= '' then
|
||||||
|
res[vim9.index_expr('kind')] = s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.bool(vim9.fn.has_key(val, 'extra')) then
|
||||||
|
res[vim9.index_expr('menu')] = vim9.index(val, 'extra')
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Isolate the command after the tag and filename.
|
||||||
|
local s = vim9.fn.matchstr(
|
||||||
|
line,
|
||||||
|
'[^\\t]*\\t[^\\t]*\\t\\zs\\(/^.*$/\\|[^\\t]*\\)\\ze\\(;"\\t\\|\\t\\|$\\)'
|
||||||
|
)
|
||||||
|
if s ~= '' then
|
||||||
|
res[vim9.index_expr('menu')] = Tagcmd2extra(
|
||||||
|
s,
|
||||||
|
vim9.index(val, 'match'),
|
||||||
|
vim9.fn.matchstr(line, '[^\\t]*\\t\\zs[^\\t]*\\ze\\t')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
Tagcmd2extra = function(cmd, name, fname)
|
||||||
|
-- # Turn a command from a tag line to something that is useful in the menu
|
||||||
|
local x = ''
|
||||||
|
if vim9.ops.RegexpMatches(cmd, '^/^') then
|
||||||
|
-- # The command is a search command, useful to see what it is.
|
||||||
|
x = vim9.fn.substitute(
|
||||||
|
vim9.fn.substitute(
|
||||||
|
vim9.fn.matchstr(cmd, '^/^\\s*\\zs.*\\ze$/'),
|
||||||
|
'\\<' .. name .. '\\>',
|
||||||
|
'@@',
|
||||||
|
''
|
||||||
|
),
|
||||||
|
'\\\\\\(.\\)',
|
||||||
|
'\\1',
|
||||||
|
'g'
|
||||||
|
) .. ' - ' .. fname
|
||||||
|
elseif vim9.bool(vim9.ops.RegexpMatches(cmd, '^\\d*$')) then
|
||||||
|
-- # The command is a line number, the file name is more useful.
|
||||||
|
x = fname .. ' - ' .. cmd
|
||||||
|
else
|
||||||
|
-- # Not recognized, use command and file name.
|
||||||
|
x = cmd .. ' - ' .. fname
|
||||||
|
end
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
|
||||||
|
Nextitem = function(lead, items, depth, all)
|
||||||
|
all = vim9.bool(all)
|
||||||
|
-- # Find composing type in "lead" and match items[0] with it.
|
||||||
|
-- # Repeat this recursively for items[1], if it's there.
|
||||||
|
-- # When resolving typedefs "depth" is used to avoid infinite recursion.
|
||||||
|
-- # Return the list of matches.
|
||||||
|
|
||||||
|
-- # Use the text up to the variable name and split it in tokens.
|
||||||
|
local tokens = vim9.fn.split(lead, '\\s\\+\\|\\<')
|
||||||
|
|
||||||
|
-- # Try to recognize the type of the variable. This is rough guessing...
|
||||||
|
local res = {}
|
||||||
|
|
||||||
|
local body = function(_, tidx)
|
||||||
|
-- # Skip tokens starting with a non-ID character.
|
||||||
|
if vim9.ops.NotRegexpMatches(vim9.index(tokens, tidx), '^\\h') then
|
||||||
|
return vim9.ITER_CONTINUE
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Recognize "struct foobar" and "union foobar".
|
||||||
|
-- # Also do "class foobar" when it's C++ after all (doesn't work very well
|
||||||
|
-- # though).
|
||||||
|
if
|
||||||
|
(
|
||||||
|
vim9.index(tokens, tidx) == 'struct'
|
||||||
|
or vim9.index(tokens, tidx) == 'union'
|
||||||
|
or vim9.index(tokens, tidx) == 'class'
|
||||||
|
) and vim9.ops.Plus(tidx, 1) < vim9.fn.len(tokens)
|
||||||
|
then
|
||||||
|
res = StructMembers(
|
||||||
|
vim9.index(tokens, tidx) .. ':' .. vim9.index(tokens, vim9.ops.Plus(tidx, 1)),
|
||||||
|
items,
|
||||||
|
all
|
||||||
|
)
|
||||||
|
return vim9.ITER_BREAK
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # TODO: add more reserved words
|
||||||
|
if
|
||||||
|
vim9.fn.index(
|
||||||
|
{ 'int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern' },
|
||||||
|
vim9.index(tokens, tidx)
|
||||||
|
) >= 0
|
||||||
|
then
|
||||||
|
return vim9.ITER_CONTINUE
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Use the tags file to find out if this is a typedef.
|
||||||
|
local diclist = vim9.fn.taglist('^' .. vim9.index(tokens, tidx) .. '$')
|
||||||
|
|
||||||
|
local body = function(_, tagidx)
|
||||||
|
local item = vim9.convert.decl_dict(vim9.index(diclist, tagidx))
|
||||||
|
|
||||||
|
-- # New ctags has the "typeref" field. Patched version has "typename".
|
||||||
|
if vim9.bool(vim9.fn.has_key(item, 'typeref')) then
|
||||||
|
res = vim9.fn.extend(res, StructMembers(vim9.index(item, 'typeref'), items, all))
|
||||||
|
return vim9.ITER_CONTINUE
|
||||||
|
end
|
||||||
|
if vim9.bool(vim9.fn.has_key(item, 'typename')) then
|
||||||
|
res = vim9.fn.extend(res, StructMembers(vim9.index(item, 'typename'), items, all))
|
||||||
|
return vim9.ITER_CONTINUE
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Only handle typedefs here.
|
||||||
|
if vim9.index(item, 'kind') ~= 't' then
|
||||||
|
return vim9.ITER_CONTINUE
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Skip matches local to another file.
|
||||||
|
if
|
||||||
|
vim9.bool(
|
||||||
|
vim9.ops.And(
|
||||||
|
vim9.ops.And(vim9.fn.has_key(item, 'static'), vim9.index(item, 'static')),
|
||||||
|
vim9.fn.bufnr('%') ~= vim9.fn.bufnr(vim9.index(item, 'filename'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
then
|
||||||
|
return vim9.ITER_CONTINUE
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # For old ctags we recognize "typedef struct aaa" and
|
||||||
|
-- # "typedef union bbb" in the tags file command.
|
||||||
|
local cmd = vim9.index(item, 'cmd')
|
||||||
|
local ei = vim9.fn.charidx(cmd, vim9.fn.matchend(cmd, 'typedef\\s\\+'))
|
||||||
|
if ei > 1 then
|
||||||
|
local cmdtokens = vim9.fn.split(vim9.slice(cmd, ei, nil), '\\s\\+\\|\\<')
|
||||||
|
if vim9.fn.len(cmdtokens) > 1 then
|
||||||
|
if
|
||||||
|
vim9.index(cmdtokens, 0) == 'struct'
|
||||||
|
or vim9.index(cmdtokens, 0) == 'union'
|
||||||
|
or vim9.index(cmdtokens, 0) == 'class'
|
||||||
|
then
|
||||||
|
local name = ''
|
||||||
|
-- # Use the first identifier after the "struct" or "union"
|
||||||
|
|
||||||
|
for _, ti in vim9.iter(vim9.fn.range((vim9.fn.len(cmdtokens) - 1))) do
|
||||||
|
if vim9.ops.RegexpMatches(vim9.index(cmdtokens, ti), '^\\w') then
|
||||||
|
name = vim9.index(cmdtokens, ti)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if name ~= '' then
|
||||||
|
res = vim9.fn.extend(
|
||||||
|
res,
|
||||||
|
StructMembers(vim9.index(cmdtokens, 0) .. ':' .. name, items, all)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
elseif vim9.bool(depth < 10) then
|
||||||
|
-- # Could be "typedef other_T some_T".
|
||||||
|
res = vim9.fn.extend(
|
||||||
|
res,
|
||||||
|
Nextitem(vim9.index(cmdtokens, 0), items, vim9.ops.Plus(depth, 1), all)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim9.ITER_DEFAULT
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, tagidx in vim9.iter(vim9.fn.range(vim9.fn.len(diclist))) do
|
||||||
|
local nvim9_status, nvim9_ret = body(_, tagidx)
|
||||||
|
if nvim9_status == vim9.ITER_BREAK then
|
||||||
|
break
|
||||||
|
elseif nvim9_status == vim9.ITER_RETURN then
|
||||||
|
return nvim9_ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.fn.len(res) > 0 then
|
||||||
|
return vim9.ITER_BREAK
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim9.ITER_DEFAULT
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, tidx in vim9.iter(vim9.fn.range(vim9.fn.len(tokens))) do
|
||||||
|
local nvim9_status, nvim9_ret = body(_, tidx)
|
||||||
|
if nvim9_status == vim9.ITER_BREAK then
|
||||||
|
break
|
||||||
|
elseif nvim9_status == vim9.ITER_RETURN then
|
||||||
|
return nvim9_ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
StructMembers = function(atypename, items, all)
|
||||||
|
all = vim9.bool(all)
|
||||||
|
|
||||||
|
-- # Search for members of structure "typename" in tags files.
|
||||||
|
-- # Return a list with resulting matches.
|
||||||
|
-- # Each match is a dictionary with "match" and "tagline" entries.
|
||||||
|
-- # When "all" is true find all, otherwise just return 1 if there is any member.
|
||||||
|
|
||||||
|
-- # Todo: What about local structures?
|
||||||
|
local fnames = vim9.fn.join(vim9.fn.map(vim9.fn.tagfiles(), function(_, v)
|
||||||
|
return vim9.fn.escape(v, ' \\#%')
|
||||||
|
end))
|
||||||
|
if fnames == '' then
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local typename = atypename
|
||||||
|
local qflist = {}
|
||||||
|
local cached = 0
|
||||||
|
local n = ''
|
||||||
|
if vim9.bool(vim9.prefix['Bang'](all)) then
|
||||||
|
n = '1'
|
||||||
|
if vim9.bool(vim9.fn.has_key(grepCache, typename)) then
|
||||||
|
qflist = vim9.index(grepCache, typename)
|
||||||
|
cached = 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
n = ''
|
||||||
|
end
|
||||||
|
if vim9.bool(vim9.prefix['Bang'](cached)) then
|
||||||
|
while 1 do
|
||||||
|
vim.api.nvim_command(
|
||||||
|
'silent! keepjumps noautocmd '
|
||||||
|
.. n
|
||||||
|
.. 'vimgrep '
|
||||||
|
.. '/\\t'
|
||||||
|
.. typename
|
||||||
|
.. '\\(\\t\\|$\\)/j '
|
||||||
|
.. fnames
|
||||||
|
)
|
||||||
|
|
||||||
|
qflist = vim9.fn.getqflist()
|
||||||
|
if vim9.fn.len(qflist) > 0 or vim9.fn.match(typename, '::') < 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- # No match for "struct:context::name", remove "context::" and try again.
|
||||||
|
typename = vim9.fn.substitute(typename, ':[^:]*::', ':', '')
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.bool(vim9.prefix['Bang'](all)) then
|
||||||
|
-- # Store the result to be able to use it again later.
|
||||||
|
grepCache[vim9.index_expr(typename)] = qflist
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Skip over [...] items
|
||||||
|
local idx = 0
|
||||||
|
local target = ''
|
||||||
|
while 1 do
|
||||||
|
if idx >= vim9.fn.len(items) then
|
||||||
|
target = ''
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if vim9.index(vim9.index(items, idx), 0) ~= '[' then
|
||||||
|
target = vim9.index(items, idx)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
-- # Put matching members in matches[].
|
||||||
|
local matches = {}
|
||||||
|
|
||||||
|
for _, l in vim9.iter(qflist) do
|
||||||
|
local memb = vim9.fn.matchstr(vim9.index(l, 'text'), '[^\\t]*')
|
||||||
|
if vim9.ops.RegexpMatches(memb, '^' .. target) then
|
||||||
|
-- # Skip matches local to another file.
|
||||||
|
if
|
||||||
|
vim9.fn.match(vim9.index(l, 'text'), '\tfile:') < 0
|
||||||
|
or vim9.fn.bufnr('%')
|
||||||
|
== vim9.fn.bufnr(vim9.fn.matchstr(vim9.index(l, 'text'), '\\t\\zs[^\\t]*'))
|
||||||
|
then
|
||||||
|
local item =
|
||||||
|
vim9.convert.decl_dict({ ['match'] = memb, ['tagline'] = vim9.index(l, 'text') })
|
||||||
|
|
||||||
|
-- # Add the kind of item.
|
||||||
|
local s =
|
||||||
|
vim9.fn.matchstr(vim9.index(l, 'text'), '\\t\\(kind:\\)\\=\\zs\\S\\ze\\(\\t\\|$\\)')
|
||||||
|
if s ~= '' then
|
||||||
|
item[vim9.index_expr('kind')] = s
|
||||||
|
if s == 'f' then
|
||||||
|
item[vim9.index_expr('match')] = memb .. '('
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vim9.fn.add(matches, item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim9.fn.len(matches) > 0 then
|
||||||
|
-- # Skip over next [...] items
|
||||||
|
idx = idx + 1
|
||||||
|
while 1 do
|
||||||
|
if idx >= vim9.fn.len(items) then
|
||||||
|
return matches
|
||||||
|
end
|
||||||
|
if vim9.index(vim9.index(items, idx), 0) ~= '[' then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # More items following. For each of the possible members find the
|
||||||
|
-- # matching following members.
|
||||||
|
return SearchMembers(matches, vim9.slice(items, idx, nil), all)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- # Failed to find anything.
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
SearchMembers = function(matches, items, all)
|
||||||
|
all = vim9.bool(all)
|
||||||
|
|
||||||
|
-- # For matching members, find matches for following items.
|
||||||
|
-- # When "all" is true find all, otherwise just return 1 if there is any member.
|
||||||
|
local res = {}
|
||||||
|
|
||||||
|
for _, i in vim9.iter(vim9.fn.range(vim9.fn.len(matches))) do
|
||||||
|
local typename = ''
|
||||||
|
local line = ''
|
||||||
|
if vim9.bool(vim9.fn.has_key(vim9.index(matches, i), 'dict')) then
|
||||||
|
if vim9.bool(vim9.fn.has_key(vim9.index(vim9.index(matches, i), 'dict'), 'typename')) then
|
||||||
|
typename = vim9.index(vim9.index(vim9.index(matches, i), 'dict'), 'typename')
|
||||||
|
elseif vim9.bool(vim9.fn.has_key(vim9.index(vim9.index(matches, i), 'dict'), 'typeref')) then
|
||||||
|
typename = vim9.index(vim9.index(vim9.index(matches, i), 'dict'), 'typeref')
|
||||||
|
end
|
||||||
|
line = '\t' .. vim9.index(vim9.index(vim9.index(matches, i), 'dict'), 'cmd')
|
||||||
|
else
|
||||||
|
line = vim9.index(vim9.index(matches, i), 'tagline')
|
||||||
|
local eb = vim9.fn.matchend(line, '\\ttypename:')
|
||||||
|
local e = vim9.fn.charidx(line, eb)
|
||||||
|
if e < 0 then
|
||||||
|
eb = vim9.fn.matchend(line, '\\ttyperef:')
|
||||||
|
e = vim9.fn.charidx(line, eb)
|
||||||
|
end
|
||||||
|
if e > 0 then
|
||||||
|
-- # Use typename field
|
||||||
|
typename = vim9.fn.matchstr(line, '[^\\t]*', eb)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if typename ~= '' then
|
||||||
|
res = vim9.fn.extend(res, StructMembers(typename, items, all))
|
||||||
|
else
|
||||||
|
-- # Use the search command (the declaration itself).
|
||||||
|
local sb = vim9.fn.match(line, '\\t\\zs/^')
|
||||||
|
local s = vim9.fn.charidx(line, sb)
|
||||||
|
if s > 0 then
|
||||||
|
local e = vim9.fn.charidx(
|
||||||
|
line,
|
||||||
|
vim9.fn.match(line, '\\<' .. vim9.index(vim9.index(matches, i), 'match') .. '\\>', sb)
|
||||||
|
)
|
||||||
|
if e > 0 then
|
||||||
|
res =
|
||||||
|
vim9.fn.extend(res, Nextitem(vim9.slice(line, s, vim9.ops.Minus(e, 1)), items, 0, all))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if vim9.bool(vim9.ops.And(vim9.prefix['Bang'](all), vim9.fn.len(res) > 0)) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
-- #}}}1
|
||||||
|
|
||||||
|
-- # vim: noet sw=2 sts=2
|
||||||
|
return M
|
@@ -1,682 +1,8 @@
|
|||||||
" Vim completion script
|
" Generated vim file by vim9jit. Please do not edit
|
||||||
" Language: C
|
let s:path = expand("<script>")
|
||||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
let s:lua_path = fnamemodify(s:path, ":r") . ".lua"
|
||||||
" Last Change: 2020 Nov 14
|
let s:nvim_module = luaeval('require("_vim9script").autoload(_A)', s:lua_path)
|
||||||
|
|
||||||
let s:cpo_save = &cpo
|
function! ccomplete#Complete(findstart, abase) abort
|
||||||
set cpo&vim
|
return s:nvim_module.Complete(a:findstart, a:abase)
|
||||||
|
endfunction
|
||||||
" This function is used for the 'omnifunc' option.
|
|
||||||
func ccomplete#Complete(findstart, base)
|
|
||||||
if a:findstart
|
|
||||||
" Locate the start of the item, including ".", "->" and "[...]".
|
|
||||||
let line = getline('.')
|
|
||||||
let start = col('.') - 1
|
|
||||||
let lastword = -1
|
|
||||||
while start > 0
|
|
||||||
if line[start - 1] =~ '\w'
|
|
||||||
let start -= 1
|
|
||||||
elseif line[start - 1] =~ '\.'
|
|
||||||
if lastword == -1
|
|
||||||
let lastword = start
|
|
||||||
endif
|
|
||||||
let start -= 1
|
|
||||||
elseif start > 1 && line[start - 2] == '-' && line[start - 1] == '>'
|
|
||||||
if lastword == -1
|
|
||||||
let lastword = start
|
|
||||||
endif
|
|
||||||
let start -= 2
|
|
||||||
elseif line[start - 1] == ']'
|
|
||||||
" Skip over [...].
|
|
||||||
let n = 0
|
|
||||||
let start -= 1
|
|
||||||
while start > 0
|
|
||||||
let start -= 1
|
|
||||||
if line[start] == '['
|
|
||||||
if n == 0
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let n -= 1
|
|
||||||
elseif line[start] == ']' " nested []
|
|
||||||
let n += 1
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
else
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
" Return the column of the last word, which is going to be changed.
|
|
||||||
" Remember the text that comes before it in s:prepended.
|
|
||||||
if lastword == -1
|
|
||||||
let s:prepended = ''
|
|
||||||
return start
|
|
||||||
endif
|
|
||||||
let s:prepended = strpart(line, start, lastword - start)
|
|
||||||
return lastword
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Return list of matches.
|
|
||||||
|
|
||||||
let base = s:prepended . a:base
|
|
||||||
|
|
||||||
" Don't do anything for an empty base, would result in all the tags in the
|
|
||||||
" tags file.
|
|
||||||
if base == ''
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
|
|
||||||
" init cache for vimgrep to empty
|
|
||||||
let s:grepCache = {}
|
|
||||||
|
|
||||||
" Split item in words, keep empty word after "." or "->".
|
|
||||||
" "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc.
|
|
||||||
" We can't use split, because we need to skip nested [...].
|
|
||||||
" "aa[...]" -> ['aa', '[...]'], "aa.bb[...]" -> ['aa', 'bb', '[...]'], etc.
|
|
||||||
let items = []
|
|
||||||
let s = 0
|
|
||||||
let arrays = 0
|
|
||||||
while 1
|
|
||||||
let e = match(base, '\.\|->\|\[', s)
|
|
||||||
if e < 0
|
|
||||||
if s == 0 || base[s - 1] != ']'
|
|
||||||
call add(items, strpart(base, s))
|
|
||||||
endif
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
if s == 0 || base[s - 1] != ']'
|
|
||||||
call add(items, strpart(base, s, e - s))
|
|
||||||
endif
|
|
||||||
if base[e] == '.'
|
|
||||||
let s = e + 1 " skip over '.'
|
|
||||||
elseif base[e] == '-'
|
|
||||||
let s = e + 2 " skip over '->'
|
|
||||||
else
|
|
||||||
" Skip over [...].
|
|
||||||
let n = 0
|
|
||||||
let s = e
|
|
||||||
let e += 1
|
|
||||||
while e < len(base)
|
|
||||||
if base[e] == ']'
|
|
||||||
if n == 0
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let n -= 1
|
|
||||||
elseif base[e] == '[' " nested [...]
|
|
||||||
let n += 1
|
|
||||||
endif
|
|
||||||
let e += 1
|
|
||||||
endwhile
|
|
||||||
let e += 1
|
|
||||||
call add(items, strpart(base, s, e - s))
|
|
||||||
let arrays += 1
|
|
||||||
let s = e
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
if complete_check()
|
|
||||||
" return v:none
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Find the variable items[0].
|
|
||||||
" 1. in current function (like with "gd")
|
|
||||||
" 2. in tags file(s) (like with ":tag")
|
|
||||||
" 3. in current file (like with "gD")
|
|
||||||
let res = []
|
|
||||||
if searchdecl(items[0], 0, 1) == 0
|
|
||||||
" Found, now figure out the type.
|
|
||||||
" TODO: join previous line if it makes sense
|
|
||||||
let line = getline('.')
|
|
||||||
let col = col('.')
|
|
||||||
if stridx(strpart(line, 0, col), ';') != -1
|
|
||||||
" Handle multiple declarations on the same line.
|
|
||||||
let col2 = col - 1
|
|
||||||
while line[col2] != ';'
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
let col2 -= 1
|
|
||||||
endwhile
|
|
||||||
let line = strpart(line, col2 + 1)
|
|
||||||
let col -= col2
|
|
||||||
endif
|
|
||||||
if stridx(strpart(line, 0, col), ',') != -1
|
|
||||||
" Handle multiple declarations on the same line in a function
|
|
||||||
" declaration.
|
|
||||||
let col2 = col - 1
|
|
||||||
while line[col2] != ','
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
let col2 -= 1
|
|
||||||
endwhile
|
|
||||||
if strpart(line, col2 + 1, col - col2 - 1) =~ ' *[^ ][^ ]* *[^ ]'
|
|
||||||
let line = strpart(line, col2 + 1)
|
|
||||||
let col -= col2
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
if len(items) == 1
|
|
||||||
" Completing one word and it's a local variable: May add '[', '.' or
|
|
||||||
" '->'.
|
|
||||||
let match = items[0]
|
|
||||||
let kind = 'v'
|
|
||||||
if match(line, '\<' . match . '\s*\[') > 0
|
|
||||||
let match .= '['
|
|
||||||
else
|
|
||||||
let res = s:Nextitem(strpart(line, 0, col), [''], 0, 1)
|
|
||||||
if len(res) > 0
|
|
||||||
" There are members, thus add "." or "->".
|
|
||||||
if match(line, '\*[ \t(]*' . match . '\>') > 0
|
|
||||||
let match .= '->'
|
|
||||||
else
|
|
||||||
let match .= '.'
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
let res = [{'match': match, 'tagline' : '', 'kind' : kind, 'info' : line}]
|
|
||||||
elseif len(items) == arrays + 1
|
|
||||||
" Completing one word and it's a local array variable: build tagline
|
|
||||||
" from declaration line
|
|
||||||
let match = items[0]
|
|
||||||
let kind = 'v'
|
|
||||||
let tagline = "\t/^" . line . '$/'
|
|
||||||
let res = [{'match': match, 'tagline' : tagline, 'kind' : kind, 'info' : line}]
|
|
||||||
else
|
|
||||||
" Completing "var.", "var.something", etc.
|
|
||||||
let res = s:Nextitem(strpart(line, 0, col), items[1:], 0, 1)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
if len(items) == 1 || len(items) == arrays + 1
|
|
||||||
" Only one part, no "." or "->": complete from tags file.
|
|
||||||
if len(items) == 1
|
|
||||||
let tags = taglist('^' . base)
|
|
||||||
else
|
|
||||||
let tags = taglist('^' . items[0] . '$')
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Remove members, these can't appear without something in front.
|
|
||||||
call filter(tags, 'has_key(v:val, "kind") ? v:val["kind"] != "m" : 1')
|
|
||||||
|
|
||||||
" Remove static matches in other files.
|
|
||||||
call filter(tags, '!has_key(v:val, "static") || !v:val["static"] || bufnr("%") == bufnr(v:val["filename"])')
|
|
||||||
|
|
||||||
call extend(res, map(tags, 's:Tag2item(v:val)'))
|
|
||||||
endif
|
|
||||||
|
|
||||||
if len(res) == 0
|
|
||||||
" Find the variable in the tags file(s)
|
|
||||||
let diclist = taglist('^' . items[0] . '$')
|
|
||||||
|
|
||||||
" Remove members, these can't appear without something in front.
|
|
||||||
call filter(diclist, 'has_key(v:val, "kind") ? v:val["kind"] != "m" : 1')
|
|
||||||
|
|
||||||
let res = []
|
|
||||||
for i in range(len(diclist))
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
" New ctags has the "typeref" field. Patched version has "typename".
|
|
||||||
if has_key(diclist[i], 'typename')
|
|
||||||
call extend(res, s:StructMembers(diclist[i]['typename'], items[1:], 1))
|
|
||||||
elseif has_key(diclist[i], 'typeref')
|
|
||||||
call extend(res, s:StructMembers(diclist[i]['typeref'], items[1:], 1))
|
|
||||||
endif
|
|
||||||
|
|
||||||
" For a variable use the command, which must be a search pattern that
|
|
||||||
" shows the declaration of the variable.
|
|
||||||
if diclist[i]['kind'] == 'v'
|
|
||||||
let line = diclist[i]['cmd']
|
|
||||||
if line[0] == '/' && line[1] == '^'
|
|
||||||
let col = match(line, '\<' . items[0] . '\>')
|
|
||||||
call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:], 0, 1))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
|
|
||||||
if len(res) == 0 && searchdecl(items[0], 1) == 0
|
|
||||||
" Found, now figure out the type.
|
|
||||||
" TODO: join previous line if it makes sense
|
|
||||||
let line = getline('.')
|
|
||||||
let col = col('.')
|
|
||||||
let res = s:Nextitem(strpart(line, 0, col), items[1:], 0, 1)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" If the last item(s) are [...] they need to be added to the matches.
|
|
||||||
let last = len(items) - 1
|
|
||||||
let brackets = ''
|
|
||||||
while last >= 0
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
if items[last][0] != '['
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let brackets = items[last] . brackets
|
|
||||||
let last -= 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
return map(res, 's:Tagline2item(v:val, brackets)')
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func s:GetAddition(line, match, memarg, bracket)
|
|
||||||
" Guess if the item is an array.
|
|
||||||
if a:bracket && match(a:line, a:match . '\s*\[') > 0
|
|
||||||
return '['
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Check if the item has members.
|
|
||||||
if len(s:SearchMembers(a:memarg, [''], 0)) > 0
|
|
||||||
" If there is a '*' before the name use "->".
|
|
||||||
if match(a:line, '\*[ \t(]*' . a:match . '\>') > 0
|
|
||||||
return '->'
|
|
||||||
else
|
|
||||||
return '.'
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return ''
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Turn the tag info "val" into an item for completion.
|
|
||||||
" "val" is is an item in the list returned by taglist().
|
|
||||||
" If it is a variable we may add "." or "->". Don't do it for other types,
|
|
||||||
" such as a typedef, by not including the info that s:GetAddition() uses.
|
|
||||||
func s:Tag2item(val)
|
|
||||||
let res = {'match': a:val['name']}
|
|
||||||
|
|
||||||
let res['extra'] = s:Tagcmd2extra(a:val['cmd'], a:val['name'], a:val['filename'])
|
|
||||||
|
|
||||||
let s = s:Dict2info(a:val)
|
|
||||||
if s != ''
|
|
||||||
let res['info'] = s
|
|
||||||
endif
|
|
||||||
|
|
||||||
let res['tagline'] = ''
|
|
||||||
if has_key(a:val, "kind")
|
|
||||||
let kind = a:val['kind']
|
|
||||||
let res['kind'] = kind
|
|
||||||
if kind == 'v'
|
|
||||||
let res['tagline'] = "\t" . a:val['cmd']
|
|
||||||
let res['dict'] = a:val
|
|
||||||
elseif kind == 'f'
|
|
||||||
let res['match'] = a:val['name'] . '('
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
return res
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Use all the items in dictionary for the "info" entry.
|
|
||||||
func s:Dict2info(dict)
|
|
||||||
let info = ''
|
|
||||||
for k in sort(keys(a:dict))
|
|
||||||
if complete_check()
|
|
||||||
return info
|
|
||||||
endif
|
|
||||||
let info .= k . repeat(' ', 10 - len(k))
|
|
||||||
if k == 'cmd'
|
|
||||||
let info .= substitute(matchstr(a:dict['cmd'], '/^\s*\zs.*\ze$/'), '\\\(.\)', '\1', 'g')
|
|
||||||
else
|
|
||||||
let info .= a:dict[k]
|
|
||||||
endif
|
|
||||||
let info .= "\n"
|
|
||||||
endfor
|
|
||||||
return info
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Parse a tag line and return a dictionary with items like taglist()
|
|
||||||
func s:ParseTagline(line)
|
|
||||||
let l = split(a:line, "\t")
|
|
||||||
let d = {}
|
|
||||||
if len(l) >= 3
|
|
||||||
let d['name'] = l[0]
|
|
||||||
let d['filename'] = l[1]
|
|
||||||
let d['cmd'] = l[2]
|
|
||||||
let n = 2
|
|
||||||
if l[2] =~ '^/'
|
|
||||||
" Find end of cmd, it may contain Tabs.
|
|
||||||
while n < len(l) && l[n] !~ '/;"$'
|
|
||||||
let n += 1
|
|
||||||
let d['cmd'] .= " " . l[n]
|
|
||||||
endwhile
|
|
||||||
endif
|
|
||||||
for i in range(n + 1, len(l) - 1)
|
|
||||||
if complete_check()
|
|
||||||
return d
|
|
||||||
endif
|
|
||||||
if l[i] == 'file:'
|
|
||||||
let d['static'] = 1
|
|
||||||
elseif l[i] !~ ':'
|
|
||||||
let d['kind'] = l[i]
|
|
||||||
else
|
|
||||||
let d[matchstr(l[i], '[^:]*')] = matchstr(l[i], ':\zs.*')
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
endif
|
|
||||||
|
|
||||||
return d
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Turn a match item "val" into an item for completion.
|
|
||||||
" "val['match']" is the matching item.
|
|
||||||
" "val['tagline']" is the tagline in which the last part was found.
|
|
||||||
func s:Tagline2item(val, brackets)
|
|
||||||
let line = a:val['tagline']
|
|
||||||
let add = s:GetAddition(line, a:val['match'], [a:val], a:brackets == '')
|
|
||||||
let res = {'word': a:val['match'] . a:brackets . add }
|
|
||||||
|
|
||||||
if has_key(a:val, 'info')
|
|
||||||
" Use info from Tag2item().
|
|
||||||
let res['info'] = a:val['info']
|
|
||||||
else
|
|
||||||
" Parse the tag line and add each part to the "info" entry.
|
|
||||||
let s = s:Dict2info(s:ParseTagline(line))
|
|
||||||
if s != ''
|
|
||||||
let res['info'] = s
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(a:val, 'kind')
|
|
||||||
let res['kind'] = a:val['kind']
|
|
||||||
elseif add == '('
|
|
||||||
let res['kind'] = 'f'
|
|
||||||
else
|
|
||||||
let s = matchstr(line, '\t\(kind:\)\=\zs\S\ze\(\t\|$\)')
|
|
||||||
if s != ''
|
|
||||||
let res['kind'] = s
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
if has_key(a:val, 'extra')
|
|
||||||
let res['menu'] = a:val['extra']
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Isolate the command after the tag and filename.
|
|
||||||
let s = matchstr(line, '[^\t]*\t[^\t]*\t\zs\(/^.*$/\|[^\t]*\)\ze\(;"\t\|\t\|$\)')
|
|
||||||
if s != ''
|
|
||||||
let res['menu'] = s:Tagcmd2extra(s, a:val['match'], matchstr(line, '[^\t]*\t\zs[^\t]*\ze\t'))
|
|
||||||
endif
|
|
||||||
return res
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Turn a command from a tag line to something that is useful in the menu
|
|
||||||
func s:Tagcmd2extra(cmd, name, fname)
|
|
||||||
if a:cmd =~ '^/^'
|
|
||||||
" The command is a search command, useful to see what it is.
|
|
||||||
let x = matchstr(a:cmd, '^/^\s*\zs.*\ze$/')
|
|
||||||
let x = substitute(x, '\<' . a:name . '\>', '@@', '')
|
|
||||||
let x = substitute(x, '\\\(.\)', '\1', 'g')
|
|
||||||
let x = x . ' - ' . a:fname
|
|
||||||
elseif a:cmd =~ '^\d*$'
|
|
||||||
" The command is a line number, the file name is more useful.
|
|
||||||
let x = a:fname . ' - ' . a:cmd
|
|
||||||
else
|
|
||||||
" Not recognized, use command and file name.
|
|
||||||
let x = a:cmd . ' - ' . a:fname
|
|
||||||
endif
|
|
||||||
return x
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Find composing type in "lead" and match items[0] with it.
|
|
||||||
" Repeat this recursively for items[1], if it's there.
|
|
||||||
" When resolving typedefs "depth" is used to avoid infinite recursion.
|
|
||||||
" Return the list of matches.
|
|
||||||
func s:Nextitem(lead, items, depth, all)
|
|
||||||
|
|
||||||
" Use the text up to the variable name and split it in tokens.
|
|
||||||
let tokens = split(a:lead, '\s\+\|\<')
|
|
||||||
|
|
||||||
" Try to recognize the type of the variable. This is rough guessing...
|
|
||||||
let res = []
|
|
||||||
for tidx in range(len(tokens))
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Skip tokens starting with a non-ID character.
|
|
||||||
if tokens[tidx] !~ '^\h'
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Recognize "struct foobar" and "union foobar".
|
|
||||||
" Also do "class foobar" when it's C++ after all (doesn't work very well
|
|
||||||
" though).
|
|
||||||
if (tokens[tidx] == 'struct' || tokens[tidx] == 'union' || tokens[tidx] == 'class') && tidx + 1 < len(tokens)
|
|
||||||
let res = s:StructMembers(tokens[tidx] . ':' . tokens[tidx + 1], a:items, a:all)
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
|
|
||||||
" TODO: add more reserved words
|
|
||||||
if index(['int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Use the tags file to find out if this is a typedef.
|
|
||||||
let diclist = taglist('^' . tokens[tidx] . '$')
|
|
||||||
for tagidx in range(len(diclist))
|
|
||||||
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
|
|
||||||
let item = diclist[tagidx]
|
|
||||||
|
|
||||||
" New ctags has the "typeref" field. Patched version has "typename".
|
|
||||||
if has_key(item, 'typeref')
|
|
||||||
call extend(res, s:StructMembers(item['typeref'], a:items, a:all))
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
if has_key(item, 'typename')
|
|
||||||
call extend(res, s:StructMembers(item['typename'], a:items, a:all))
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Only handle typedefs here.
|
|
||||||
if item['kind'] != 't'
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Skip matches local to another file.
|
|
||||||
if has_key(item, 'static') && item['static'] && bufnr('%') != bufnr(item['filename'])
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
" For old ctags we recognize "typedef struct aaa" and
|
|
||||||
" "typedef union bbb" in the tags file command.
|
|
||||||
let cmd = item['cmd']
|
|
||||||
let ei = matchend(cmd, 'typedef\s\+')
|
|
||||||
if ei > 1
|
|
||||||
let cmdtokens = split(strpart(cmd, ei), '\s\+\|\<')
|
|
||||||
if len(cmdtokens) > 1
|
|
||||||
if cmdtokens[0] == 'struct' || cmdtokens[0] == 'union' || cmdtokens[0] == 'class'
|
|
||||||
let name = ''
|
|
||||||
" Use the first identifier after the "struct" or "union"
|
|
||||||
for ti in range(len(cmdtokens) - 1)
|
|
||||||
if cmdtokens[ti] =~ '^\w'
|
|
||||||
let name = cmdtokens[ti]
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
if name != ''
|
|
||||||
call extend(res, s:StructMembers(cmdtokens[0] . ':' . name, a:items, a:all))
|
|
||||||
endif
|
|
||||||
elseif a:depth < 10
|
|
||||||
" Could be "typedef other_T some_T".
|
|
||||||
call extend(res, s:Nextitem(cmdtokens[0], a:items, a:depth + 1, a:all))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
if len(res) > 0
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return res
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
|
|
||||||
" Search for members of structure "typename" in tags files.
|
|
||||||
" Return a list with resulting matches.
|
|
||||||
" Each match is a dictionary with "match" and "tagline" entries.
|
|
||||||
" When "all" is non-zero find all, otherwise just return 1 if there is any
|
|
||||||
" member.
|
|
||||||
func s:StructMembers(typename, items, all)
|
|
||||||
" Todo: What about local structures?
|
|
||||||
let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
|
|
||||||
if fnames == ''
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
|
|
||||||
let typename = a:typename
|
|
||||||
let qflist = []
|
|
||||||
let cached = 0
|
|
||||||
if a:all == 0
|
|
||||||
let n = '1' " stop at first found match
|
|
||||||
if has_key(s:grepCache, a:typename)
|
|
||||||
let qflist = s:grepCache[a:typename]
|
|
||||||
let cached = 1
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let n = ''
|
|
||||||
endif
|
|
||||||
if !cached
|
|
||||||
while 1
|
|
||||||
if complete_check()
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
exe 'silent! keepj noautocmd ' . n . 'vimgrep /\t' . typename . '\(\t\|$\)/j ' . fnames
|
|
||||||
|
|
||||||
let qflist = getqflist()
|
|
||||||
if len(qflist) > 0 || match(typename, "::") < 0
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
" No match for "struct:context::name", remove "context::" and try again.
|
|
||||||
let typename = substitute(typename, ':[^:]*::', ':', '')
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
if a:all == 0
|
|
||||||
" Store the result to be able to use it again later.
|
|
||||||
let s:grepCache[a:typename] = qflist
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Skip over [...] items
|
|
||||||
let idx = 0
|
|
||||||
while 1
|
|
||||||
if complete_check()
|
|
||||||
return []
|
|
||||||
endif
|
|
||||||
if idx >= len(a:items)
|
|
||||||
let target = '' " No further items, matching all members
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
if a:items[idx][0] != '['
|
|
||||||
let target = a:items[idx]
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let idx += 1
|
|
||||||
endwhile
|
|
||||||
" Put matching members in matches[].
|
|
||||||
let matches = []
|
|
||||||
for l in qflist
|
|
||||||
let memb = matchstr(l['text'], '[^\t]*')
|
|
||||||
if memb =~ '^' . target
|
|
||||||
" Skip matches local to another file.
|
|
||||||
if match(l['text'], "\tfile:") < 0 || bufnr('%') == bufnr(matchstr(l['text'], '\t\zs[^\t]*'))
|
|
||||||
let item = {'match': memb, 'tagline': l['text']}
|
|
||||||
|
|
||||||
" Add the kind of item.
|
|
||||||
let s = matchstr(l['text'], '\t\(kind:\)\=\zs\S\ze\(\t\|$\)')
|
|
||||||
if s != ''
|
|
||||||
let item['kind'] = s
|
|
||||||
if s == 'f'
|
|
||||||
let item['match'] = memb . '('
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
call add(matches, item)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
|
|
||||||
if len(matches) > 0
|
|
||||||
" Skip over next [...] items
|
|
||||||
let idx += 1
|
|
||||||
while 1
|
|
||||||
if complete_check()
|
|
||||||
return matches
|
|
||||||
endif
|
|
||||||
if idx >= len(a:items)
|
|
||||||
return matches " No further items, return the result.
|
|
||||||
endif
|
|
||||||
if a:items[idx][0] != '['
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
let idx += 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
" More items following. For each of the possible members find the
|
|
||||||
" matching following members.
|
|
||||||
return s:SearchMembers(matches, a:items[idx :], a:all)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Failed to find anything.
|
|
||||||
return []
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" For matching members, find matches for following items.
|
|
||||||
" When "all" is non-zero find all, otherwise just return 1 if there is any
|
|
||||||
" member.
|
|
||||||
func s:SearchMembers(matches, items, all)
|
|
||||||
let res = []
|
|
||||||
for i in range(len(a:matches))
|
|
||||||
if complete_check()
|
|
||||||
return res
|
|
||||||
endif
|
|
||||||
let typename = ''
|
|
||||||
if has_key(a:matches[i], 'dict')
|
|
||||||
if has_key(a:matches[i].dict, 'typename')
|
|
||||||
let typename = a:matches[i].dict['typename']
|
|
||||||
elseif has_key(a:matches[i].dict, 'typeref')
|
|
||||||
let typename = a:matches[i].dict['typeref']
|
|
||||||
endif
|
|
||||||
let line = "\t" . a:matches[i].dict['cmd']
|
|
||||||
else
|
|
||||||
let line = a:matches[i]['tagline']
|
|
||||||
let e = matchend(line, '\ttypename:')
|
|
||||||
if e < 0
|
|
||||||
let e = matchend(line, '\ttyperef:')
|
|
||||||
endif
|
|
||||||
if e > 0
|
|
||||||
" Use typename field
|
|
||||||
let typename = matchstr(line, '[^\t]*', e)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
if typename != ''
|
|
||||||
call extend(res, s:StructMembers(typename, a:items, a:all))
|
|
||||||
else
|
|
||||||
" Use the search command (the declaration itself).
|
|
||||||
let s = match(line, '\t\zs/^')
|
|
||||||
if s > 0
|
|
||||||
let e = match(line, '\<' . a:matches[i]['match'] . '\>', s)
|
|
||||||
if e > 0
|
|
||||||
call extend(res, s:Nextitem(strpart(line, s, e - s), a:items, 0, a:all))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
if a:all == 0 && len(res) > 0
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
return res
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
let &cpo = s:cpo_save
|
|
||||||
unlet s:cpo_save
|
|
||||||
|
|
||||||
" vim: noet sw=2 sts=2
|
|
||||||
|
@@ -2,21 +2,6 @@
|
|||||||
" Maintainer: Gregory Anders
|
" Maintainer: Gregory Anders
|
||||||
" Last Change: 2024-09-03
|
" Last Change: 2024-09-03
|
||||||
" Based on: https://github.com/hashivim/vim-terraform
|
" Based on: https://github.com/hashivim/vim-terraform
|
||||||
" License: ISC
|
|
||||||
"
|
|
||||||
" Copyright (c) 2014-2016 Mark Cornick <mark@markcornick.com>
|
|
||||||
"
|
|
||||||
" Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
||||||
" with or without fee is hereby granted, provided that the above copyright notice
|
|
||||||
" and this permission notice appear in all copies.
|
|
||||||
"
|
|
||||||
" THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
||||||
" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
" FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
||||||
" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
||||||
" OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
||||||
" THIS SOFTWARE.
|
|
||||||
|
|
||||||
function! hcl#indentexpr(lnum)
|
function! hcl#indentexpr(lnum)
|
||||||
" Beginning of the file should have no indent
|
" Beginning of the file should have no indent
|
||||||
|
@@ -1,192 +0,0 @@
|
|||||||
" HTML folding script, :h ft-html-plugin
|
|
||||||
" Latest Change: 2025 May 10
|
|
||||||
" Original Author: Aliaksei Budavei <0x000c70@gmail.com>
|
|
||||||
|
|
||||||
function! htmlfold#MapBalancedTags() abort
|
|
||||||
" Describe only _a capturable-name prefix_ for start and end patterns of
|
|
||||||
" a tag so that start tags with attributes spanning across lines can also be
|
|
||||||
" matched with a single call of "getline()".
|
|
||||||
let tag = '\m\c</\=\([0-9A-Za-z-]\+\)'
|
|
||||||
let names = []
|
|
||||||
let pairs = []
|
|
||||||
let ends = []
|
|
||||||
let pos = getpos('.')
|
|
||||||
|
|
||||||
try
|
|
||||||
call cursor(1, 1)
|
|
||||||
let [lnum, cnum] = searchpos(tag, 'cnW')
|
|
||||||
|
|
||||||
" Pair up nearest non-inlined tags in scope.
|
|
||||||
while lnum > 0
|
|
||||||
let name_attr = synIDattr(synID(lnum, cnum, 0), 'name')
|
|
||||||
|
|
||||||
if name_attr ==# 'htmlTag' || name_attr ==# 'htmlScriptTag'
|
|
||||||
let name = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
|
||||||
|
|
||||||
if !empty(name)
|
|
||||||
call insert(names, tolower(name), 0)
|
|
||||||
call insert(pairs, [lnum, -1], 0)
|
|
||||||
endif
|
|
||||||
elseif name_attr ==# 'htmlEndTag'
|
|
||||||
let name = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
|
||||||
|
|
||||||
if !empty(name)
|
|
||||||
let idx = index(names, tolower(name))
|
|
||||||
|
|
||||||
if idx >= 0
|
|
||||||
" Dismiss inlined balanced tags and opened-only tags.
|
|
||||||
if pairs[idx][0] != lnum
|
|
||||||
let pairs[idx][1] = lnum
|
|
||||||
call add(ends, lnum)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Claim a pair.
|
|
||||||
let names[: idx] = repeat([''], (idx + 1))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Advance the cursor, at "<", past "</a", "<a>", etc.
|
|
||||||
call cursor(lnum, (cnum + 3))
|
|
||||||
let [lnum, cnum] = searchpos(tag, 'cnW')
|
|
||||||
endwhile
|
|
||||||
finally
|
|
||||||
call setpos('.', pos)
|
|
||||||
endtry
|
|
||||||
|
|
||||||
if empty(ends)
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
let folds = {}
|
|
||||||
let pending_end = ends[0]
|
|
||||||
let level = 0
|
|
||||||
|
|
||||||
while !empty(pairs)
|
|
||||||
let [start, end] = remove(pairs, -1)
|
|
||||||
|
|
||||||
if end < 0
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
if start >= pending_end
|
|
||||||
" Mark a sibling tag.
|
|
||||||
call remove(ends, 0)
|
|
||||||
|
|
||||||
while start >= ends[0]
|
|
||||||
" Mark a parent tag.
|
|
||||||
call remove(ends, 0)
|
|
||||||
let level -= 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
let pending_end = ends[0]
|
|
||||||
else
|
|
||||||
" Mark a child tag.
|
|
||||||
let level += 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Flatten the innermost inlined folds.
|
|
||||||
let folds[start] = get(folds, start, ('>' . level))
|
|
||||||
let folds[end] = get(folds, end, ('<' . level))
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
return folds
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" See ":help vim9-mix".
|
|
||||||
if !has("vim9script")
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
|
|
||||||
def! g:htmlfold#MapBalancedTags(): dict<string>
|
|
||||||
# Describe only _a capturable-name prefix_ for start and end patterns of
|
|
||||||
# a tag so that start tags with attributes spanning across lines can also be
|
|
||||||
# matched with a single call of "getline()".
|
|
||||||
const tag: string = '\m\c</\=\([0-9A-Za-z-]\+\)'
|
|
||||||
var names: list<string> = []
|
|
||||||
var pairs: list<list<number>> = []
|
|
||||||
var ends: list<number> = []
|
|
||||||
const pos: list<number> = getpos('.')
|
|
||||||
|
|
||||||
try
|
|
||||||
cursor(1, 1)
|
|
||||||
var [lnum: number, cnum: number] = searchpos(tag, 'cnW')
|
|
||||||
|
|
||||||
# Pair up nearest non-inlined tags in scope.
|
|
||||||
while lnum > 0
|
|
||||||
const name_attr: string = synIDattr(synID(lnum, cnum, 0), 'name')
|
|
||||||
|
|
||||||
if name_attr ==# 'htmlTag' || name_attr ==# 'htmlScriptTag'
|
|
||||||
const name: string = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
|
||||||
|
|
||||||
if !empty(name)
|
|
||||||
insert(names, tolower(name), 0)
|
|
||||||
insert(pairs, [lnum, -1], 0)
|
|
||||||
endif
|
|
||||||
elseif name_attr ==# 'htmlEndTag'
|
|
||||||
const name: string = get(matchlist(getline(lnum), tag, (cnum - 1)), 1, '')
|
|
||||||
|
|
||||||
if !empty(name)
|
|
||||||
const idx: number = index(names, tolower(name))
|
|
||||||
|
|
||||||
if idx >= 0
|
|
||||||
# Dismiss inlined balanced tags and opened-only tags.
|
|
||||||
if pairs[idx][0] != lnum
|
|
||||||
pairs[idx][1] = lnum
|
|
||||||
add(ends, lnum)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Claim a pair.
|
|
||||||
names[: idx] = repeat([''], (idx + 1))
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Advance the cursor, at "<", past "</a", "<a>", etc.
|
|
||||||
cursor(lnum, (cnum + 3))
|
|
||||||
[lnum, cnum] = searchpos(tag, 'cnW')
|
|
||||||
endwhile
|
|
||||||
finally
|
|
||||||
setpos('.', pos)
|
|
||||||
endtry
|
|
||||||
|
|
||||||
if empty(ends)
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
var folds: dict<string> = {}
|
|
||||||
var pending_end: number = ends[0]
|
|
||||||
var level: number = 0
|
|
||||||
|
|
||||||
while !empty(pairs)
|
|
||||||
const [start: number, end: number] = remove(pairs, -1)
|
|
||||||
|
|
||||||
if end < 0
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
|
|
||||||
if start >= pending_end
|
|
||||||
# Mark a sibling tag.
|
|
||||||
remove(ends, 0)
|
|
||||||
|
|
||||||
while start >= ends[0]
|
|
||||||
# Mark a parent tag.
|
|
||||||
remove(ends, 0)
|
|
||||||
level -= 1
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
pending_end = ends[0]
|
|
||||||
else
|
|
||||||
# Mark a child tag.
|
|
||||||
level += 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Flatten the innermost inlined folds.
|
|
||||||
folds[start] = get(folds, start, ('>' .. level))
|
|
||||||
folds[end] = get(folds, end, ('<' .. level))
|
|
||||||
endwhile
|
|
||||||
|
|
||||||
return folds
|
|
||||||
enddef
|
|
||||||
|
|
||||||
" vim: fdm=syntax sw=2 ts=8 noet
|
|
@@ -85,10 +85,10 @@ function! s:set_wayland() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:set_wayclip() abort
|
function! s:set_wayclip() abort
|
||||||
let s:copy['+'] = ['waycopy']
|
let s:copy['+'] = ['waycopy', '-t', 'text/plain']
|
||||||
let s:paste['+'] = ['waypaste']
|
let s:paste['+'] = ['waypaste', '-t', 'text/plain']
|
||||||
let s:copy['*'] = ['waycopy', '-p']
|
let s:copy['*'] = s:copy['+']
|
||||||
let s:paste['*'] = ['waypaste', '-p']
|
let s:paste['*'] = s:paste['+']
|
||||||
return 'wayclip'
|
return 'wayclip'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@@ -1,8 +1,5 @@
|
|||||||
" Author: Stephen Sugden <stephen@stephensugden.com>
|
" Author: Stephen Sugden <stephen@stephensugden.com>
|
||||||
" Last Modified: 2023-09-11
|
" Last Modified: 2023-09-11
|
||||||
" Last Change:
|
|
||||||
" 2025 Mar 31 by Vim project (rename s:RustfmtConfigOptions())
|
|
||||||
" 2025 Jul 14 by Vim project (don't parse rustfmt version automatically #17745)
|
|
||||||
"
|
"
|
||||||
" Adapted from https://github.com/fatih/vim-go
|
" Adapted from https://github.com/fatih/vim-go
|
||||||
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim
|
||||||
@@ -24,12 +21,6 @@ if !exists("g:rustfmt_fail_silently")
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
function! rustfmt#DetectVersion()
|
function! rustfmt#DetectVersion()
|
||||||
let s:rustfmt_version = "0"
|
|
||||||
let s:rustfmt_help = ""
|
|
||||||
let s:rustfmt_unstable_features = ""
|
|
||||||
if !get(g:, 'rustfmt_detect_version', 0)
|
|
||||||
return s:rustfmt_version
|
|
||||||
endif
|
|
||||||
" Save rustfmt '--help' for feature inspection
|
" Save rustfmt '--help' for feature inspection
|
||||||
silent let s:rustfmt_help = system(g:rustfmt_command . " --help")
|
silent let s:rustfmt_help = system(g:rustfmt_command . " --help")
|
||||||
let s:rustfmt_unstable_features = s:rustfmt_help =~# "--unstable-features"
|
let s:rustfmt_unstable_features = s:rustfmt_help =~# "--unstable-features"
|
||||||
@@ -38,7 +29,9 @@ function! rustfmt#DetectVersion()
|
|||||||
silent let l:rustfmt_version_full = system(g:rustfmt_command . " --version")
|
silent let l:rustfmt_version_full = system(g:rustfmt_command . " --version")
|
||||||
let l:rustfmt_version_list = matchlist(l:rustfmt_version_full,
|
let l:rustfmt_version_list = matchlist(l:rustfmt_version_full,
|
||||||
\ '\vrustfmt ([0-9]+[.][0-9]+[.][0-9]+)')
|
\ '\vrustfmt ([0-9]+[.][0-9]+[.][0-9]+)')
|
||||||
if len(l:rustfmt_version_list) >= 3
|
if len(l:rustfmt_version_list) < 3
|
||||||
|
let s:rustfmt_version = "0"
|
||||||
|
else
|
||||||
let s:rustfmt_version = l:rustfmt_version_list[1]
|
let s:rustfmt_version = l:rustfmt_version_list[1]
|
||||||
endif
|
endif
|
||||||
return s:rustfmt_version
|
return s:rustfmt_version
|
||||||
@@ -68,13 +61,7 @@ function! s:RustfmtWriteMode()
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! rustfmt#RustfmtConfigOptions()
|
function! s:RustfmtConfigOptions()
|
||||||
let default = '--edition 2018'
|
|
||||||
|
|
||||||
if !get(g:, 'rustfmt_find_toml', 0)
|
|
||||||
return default
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:rustfmt_toml = findfile('rustfmt.toml', expand('%:p:h') . ';')
|
let l:rustfmt_toml = findfile('rustfmt.toml', expand('%:p:h') . ';')
|
||||||
if l:rustfmt_toml !=# ''
|
if l:rustfmt_toml !=# ''
|
||||||
return '--config-path '.shellescape(fnamemodify(l:rustfmt_toml, ":p"))
|
return '--config-path '.shellescape(fnamemodify(l:rustfmt_toml, ":p"))
|
||||||
@@ -86,7 +73,7 @@ function! rustfmt#RustfmtConfigOptions()
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
" Default to edition 2018 in case no rustfmt.toml was found.
|
" Default to edition 2018 in case no rustfmt.toml was found.
|
||||||
return default
|
return '--edition 2018'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:RustfmtCommandRange(filename, line1, line2)
|
function! s:RustfmtCommandRange(filename, line1, line2)
|
||||||
@@ -97,7 +84,7 @@ function! s:RustfmtCommandRange(filename, line1, line2)
|
|||||||
|
|
||||||
let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
|
let l:arg = {"file": shellescape(a:filename), "range": [a:line1, a:line2]}
|
||||||
let l:write_mode = s:RustfmtWriteMode()
|
let l:write_mode = s:RustfmtWriteMode()
|
||||||
let l:rustfmt_config = rustfmt#RustfmtConfigOptions()
|
let l:rustfmt_config = s:RustfmtConfigOptions()
|
||||||
|
|
||||||
" FIXME: When --file-lines gets to be stable, add version range checking
|
" FIXME: When --file-lines gets to be stable, add version range checking
|
||||||
" accordingly.
|
" accordingly.
|
||||||
@@ -112,7 +99,7 @@ endfunction
|
|||||||
|
|
||||||
function! s:RustfmtCommand()
|
function! s:RustfmtCommand()
|
||||||
let write_mode = g:rustfmt_emit_files ? '--emit=stdout' : '--write-mode=display'
|
let write_mode = g:rustfmt_emit_files ? '--emit=stdout' : '--write-mode=display'
|
||||||
let config = rustfmt#RustfmtConfigOptions()
|
let config = s:RustfmtConfigOptions()
|
||||||
return join([g:rustfmt_command, write_mode, config, g:rustfmt_options])
|
return join([g:rustfmt_command, write_mode, config, g:rustfmt_options])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@@ -12,11 +12,6 @@
|
|||||||
" 2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
|
" 2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
|
||||||
" 2025 Mar 01 by Vim Project: fix syntax error in tar#Read()
|
" 2025 Mar 01 by Vim Project: fix syntax error in tar#Read()
|
||||||
" 2025 Mar 02 by Vim Project: escape the filename before using :read
|
" 2025 Mar 02 by Vim Project: escape the filename before using :read
|
||||||
" 2025 Mar 02 by Vim Project: determine the compression using readblob()
|
|
||||||
" instead of shelling out to file(1)
|
|
||||||
" 2025 Apr 16 by Vim Project: decouple from netrw by adding s:WinPath()
|
|
||||||
" 2025 May 19 by Vim Project: restore working directory after read/write
|
|
||||||
" 2025 Jul 13 by Vim Project: warn with path traversal attacks
|
|
||||||
"
|
"
|
||||||
" Contains many ideas from Michael Toren's <tar.vim>
|
" Contains many ideas from Michael Toren's <tar.vim>
|
||||||
"
|
"
|
||||||
@@ -35,9 +30,9 @@ if &cp || exists("g:loaded_tar")
|
|||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
let g:loaded_tar= "v32b"
|
let g:loaded_tar= "v32b"
|
||||||
if !has('nvim-0.12') && v:version < 900
|
if v:version < 702
|
||||||
echohl WarningMsg
|
echohl WarningMsg
|
||||||
echo "***warning*** this version of tar needs vim 9.0"
|
echo "***warning*** this version of tar needs vim 7.2"
|
||||||
echohl Normal
|
echohl Normal
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
@@ -47,10 +42,10 @@ set cpo&vim
|
|||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
" Default Settings: {{{1
|
" Default Settings: {{{1
|
||||||
if !exists("g:tar_browseoptions")
|
if !exists("g:tar_browseoptions")
|
||||||
let g:tar_browseoptions= "tf"
|
let g:tar_browseoptions= "Ptf"
|
||||||
endif
|
endif
|
||||||
if !exists("g:tar_readoptions")
|
if !exists("g:tar_readoptions")
|
||||||
let g:tar_readoptions= "pxf"
|
let g:tar_readoptions= "pPxf"
|
||||||
endif
|
endif
|
||||||
if !exists("g:tar_cmd")
|
if !exists("g:tar_cmd")
|
||||||
let g:tar_cmd= "tar"
|
let g:tar_cmd= "tar"
|
||||||
@@ -59,7 +54,6 @@ if !exists("g:tar_writeoptions")
|
|||||||
let g:tar_writeoptions= "uf"
|
let g:tar_writeoptions= "uf"
|
||||||
endif
|
endif
|
||||||
if !exists("g:tar_delfile")
|
if !exists("g:tar_delfile")
|
||||||
" Note: not supported on BSD
|
|
||||||
let g:tar_delfile="--delete -f"
|
let g:tar_delfile="--delete -f"
|
||||||
endif
|
endif
|
||||||
if !exists("g:netrw_cygwin")
|
if !exists("g:netrw_cygwin")
|
||||||
@@ -108,26 +102,10 @@ if !exists("g:tar_shq")
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let g:tar_secure=' -- '
|
|
||||||
let g:tar_leading_pat='^\%([.]\{,2\}/\)\+'
|
|
||||||
|
|
||||||
" ----------------
|
" ----------------
|
||||||
" Functions: {{{1
|
" Functions: {{{1
|
||||||
" ----------------
|
" ----------------
|
||||||
|
|
||||||
" ---------------------------------------------------------------------
|
|
||||||
" s:Msg: {{{2
|
|
||||||
fun! s:Msg(func, severity, msg)
|
|
||||||
redraw!
|
|
||||||
if a:severity =~? 'error'
|
|
||||||
echohl Error
|
|
||||||
else
|
|
||||||
echohl WarningMsg
|
|
||||||
endif
|
|
||||||
echo $"***{a:severity}*** ({a:func}) {a:msg}"
|
|
||||||
echohl None
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
" tar#Browse: {{{2
|
" tar#Browse: {{{2
|
||||||
fun! tar#Browse(tarfile)
|
fun! tar#Browse(tarfile)
|
||||||
@@ -136,14 +114,16 @@ fun! tar#Browse(tarfile)
|
|||||||
|
|
||||||
" sanity checks
|
" sanity checks
|
||||||
if !executable(g:tar_cmd)
|
if !executable(g:tar_cmd)
|
||||||
call s:Msg('tar#Browse', 'error', $"{g:tar_cmd} not available on your system")
|
redraw!
|
||||||
|
echohl Error | echo '***error*** (tar#Browse) "'.g:tar_cmd.'" not available on your system'
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
if !filereadable(a:tarfile)
|
if !filereadable(a:tarfile)
|
||||||
if a:tarfile !~# '^\a\+://'
|
if a:tarfile !~# '^\a\+://'
|
||||||
" if it's an url, don't complain, let url-handlers such as vim do its thing
|
" if it's an url, don't complain, let url-handlers such as vim do its thing
|
||||||
call s:Msg('tar#Browse', 'error', $"File not readable<{a:tarfile}>")
|
redraw!
|
||||||
|
echohl Error | echo "***error*** (tar#Browse) File not readable<".a:tarfile.">" | echohl None
|
||||||
endif
|
endif
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
return
|
return
|
||||||
@@ -164,7 +144,7 @@ fun! tar#Browse(tarfile)
|
|||||||
let lastline= line("$")
|
let lastline= line("$")
|
||||||
call setline(lastline+1,'" tar.vim version '.g:loaded_tar)
|
call setline(lastline+1,'" tar.vim version '.g:loaded_tar)
|
||||||
call setline(lastline+2,'" Browsing tarfile '.a:tarfile)
|
call setline(lastline+2,'" Browsing tarfile '.a:tarfile)
|
||||||
call setline(lastline+3,'" Select a file with cursor and press ENTER, "x" to extract a file')
|
call setline(lastline+3,'" Select a file with cursor and press ENTER')
|
||||||
keepj $put =''
|
keepj $put =''
|
||||||
keepj sil! 0d
|
keepj sil! 0d
|
||||||
keepj $
|
keepj $
|
||||||
@@ -181,19 +161,23 @@ fun! tar#Browse(tarfile)
|
|||||||
|
|
||||||
elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' ||
|
elseif tarfile =~# '\.\(tgz\)$' || tarfile =~# '\.\(tbz\)$' || tarfile =~# '\.\(txz\)$' ||
|
||||||
\ tarfile =~# '\.\(tzst\)$' || tarfile =~# '\.\(tlz4\)$'
|
\ tarfile =~# '\.\(tzst\)$' || tarfile =~# '\.\(tlz4\)$'
|
||||||
let header= s:Header(tarfile)
|
if has("unix") && executable("file")
|
||||||
|
let filekind= system("file ".shellescape(tarfile,1))
|
||||||
|
else
|
||||||
|
let filekind= ""
|
||||||
|
endif
|
||||||
|
|
||||||
if header =~? 'bzip2'
|
if filekind =~ "bzip2"
|
||||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||||
elseif header =~? 'bzip3'
|
elseif filekind =~ "bzip3"
|
||||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||||
elseif header =~? 'xz'
|
elseif filekind =~ "XZ"
|
||||||
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||||
elseif header =~? 'zstd'
|
elseif filekind =~ "Zstandard"
|
||||||
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||||
elseif header =~? 'lz4'
|
elseif filekind =~ "LZ4"
|
||||||
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||||
elseif header =~? 'gzip'
|
else
|
||||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_browseoptions." - "
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -219,18 +203,28 @@ fun! tar#Browse(tarfile)
|
|||||||
exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1)
|
exe "sil! r! ".g:tar_cmd." -".g:tar_browseoptions." ".shellescape(tarfile,1)
|
||||||
endif
|
endif
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Browse', 'warning', $"please check your g:tar_browseoptions '<{g:tar_browseoptions}>'")
|
redraw!
|
||||||
|
echohl WarningMsg | echo "***warning*** (tar#Browse) please check your g:tar_browseoptions<".g:tar_browseoptions.">"
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
"
|
||||||
" remove tar: Removing leading '/' from member names
|
" The following should not be neccessary, since in case of errors the
|
||||||
" Note: the message could be localized
|
" previous if statement should have caught the problem (because tar exited
|
||||||
if search('^tar: ') > 0 || search(g:tar_leading_pat) > 0
|
" with a non-zero exit code).
|
||||||
call append(3,'" Note: Path Traversal Attack detected!')
|
" if line("$") == curlast || ( line("$") == (curlast + 1) &&
|
||||||
let b:leading_slash = 1
|
" \ getline("$") =~# '\c\<\%(warning\|error\|inappropriate\|unrecognized\)\>' &&
|
||||||
" remove the message output
|
" \ getline("$") =~ '\s' )
|
||||||
sil g/^tar: /d
|
" redraw!
|
||||||
endif
|
" echohl WarningMsg | echo "***warning*** (tar#Browse) ".a:tarfile." doesn't appear to be a tar file" | echohl None
|
||||||
|
" keepj sil! %d
|
||||||
|
" let eikeep= &ei
|
||||||
|
" set ei=BufReadCmd,FileReadCmd
|
||||||
|
" exe "r ".fnameescape(a:tarfile)
|
||||||
|
" let &ei= eikeep
|
||||||
|
" keepj sil! 1d
|
||||||
|
" call Dret("tar#Browse : a:tarfile<".a:tarfile.">")
|
||||||
|
" return
|
||||||
|
" endif
|
||||||
|
|
||||||
" set up maps supported for tar
|
" set up maps supported for tar
|
||||||
setlocal noma nomod ro
|
setlocal noma nomod ro
|
||||||
@@ -249,7 +243,12 @@ fun! s:TarBrowseSelect()
|
|||||||
let repkeep= &report
|
let repkeep= &report
|
||||||
set report=10
|
set report=10
|
||||||
let fname= getline(".")
|
let fname= getline(".")
|
||||||
let ls= get(b:, 'leading_slash', 0)
|
|
||||||
|
if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
|
||||||
|
redraw!
|
||||||
|
echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
" sanity check
|
" sanity check
|
||||||
if fname =~ '^"'
|
if fname =~ '^"'
|
||||||
@@ -271,8 +270,7 @@ fun! s:TarBrowseSelect()
|
|||||||
wincmd _
|
wincmd _
|
||||||
endif
|
endif
|
||||||
let s:tblfile_{winnr()}= curfile
|
let s:tblfile_{winnr()}= curfile
|
||||||
let b:leading_slash= ls
|
call tar#Read("tarfile:".tarfile.'::'.fname,1)
|
||||||
call tar#Read("tarfile:".tarfile.'::'.fname)
|
|
||||||
filetype detect
|
filetype detect
|
||||||
set nomod
|
set nomod
|
||||||
exe 'com! -buffer -nargs=? -complete=file TarDiff :call tar#Diff(<q-args>,"'.fnameescape(fname).'")'
|
exe 'com! -buffer -nargs=? -complete=file TarDiff :call tar#Diff(<q-args>,"'.fnameescape(fname).'")'
|
||||||
@@ -282,18 +280,26 @@ endfun
|
|||||||
|
|
||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
" tar#Read: {{{2
|
" tar#Read: {{{2
|
||||||
fun! tar#Read(fname)
|
fun! tar#Read(fname,mode)
|
||||||
let repkeep= &report
|
let repkeep= &report
|
||||||
set report=10
|
set report=10
|
||||||
let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
|
let tarfile = substitute(a:fname,'tarfile:\(.\{-}\)::.*$','\1','')
|
||||||
let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
|
let fname = substitute(a:fname,'tarfile:.\{-}::\(.*\)$','\1','')
|
||||||
" be careful not to execute special crafted files
|
" be careful not to execute special crafted files
|
||||||
let escape_file = fname->substitute(g:tar_leading_pat, '', '')->fnameescape()
|
let escape_file = fname->fnameescape()
|
||||||
|
|
||||||
|
" changing the directory to the temporary earlier to allow tar to extract the file with permissions intact
|
||||||
|
if !exists("*mkdir")
|
||||||
|
redraw!
|
||||||
|
echohl Error | echo "***error*** (tar#Write) sorry, mkdir() doesn't work on your system" | echohl None
|
||||||
|
let &report= repkeep
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
let curdir= getcwd()
|
let curdir= getcwd()
|
||||||
let b:curdir= curdir
|
|
||||||
let tmpdir= tempname()
|
let tmpdir= tempname()
|
||||||
let b:tmpdir= tmpdir
|
let b:curdir= tmpdir
|
||||||
|
let b:tmpdir= curdir
|
||||||
if tmpdir =~ '\.'
|
if tmpdir =~ '\.'
|
||||||
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
||||||
endif
|
endif
|
||||||
@@ -301,9 +307,10 @@ fun! tar#Read(fname)
|
|||||||
|
|
||||||
" attempt to change to the indicated directory
|
" attempt to change to the indicated directory
|
||||||
try
|
try
|
||||||
exe "lcd ".fnameescape(tmpdir)
|
exe "cd ".fnameescape(tmpdir)
|
||||||
catch /^Vim\%((\a\+)\)\=:E344/
|
catch /^Vim\%((\a\+)\)\=:E344/
|
||||||
call s:Msg('tar#Read', 'error', "cannot lcd to temporary directory")
|
redraw!
|
||||||
|
echohl Error | echo "***error*** (tar#Write) cannot cd to temporary directory" | Echohl None
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
return
|
return
|
||||||
endtry
|
endtry
|
||||||
@@ -313,7 +320,7 @@ fun! tar#Read(fname)
|
|||||||
call s:Rmdir("_ZIPVIM_")
|
call s:Rmdir("_ZIPVIM_")
|
||||||
endif
|
endif
|
||||||
call mkdir("_ZIPVIM_")
|
call mkdir("_ZIPVIM_")
|
||||||
lcd _ZIPVIM_
|
cd _ZIPVIM_
|
||||||
|
|
||||||
if has("win32unix") && executable("cygpath")
|
if has("win32unix") && executable("cygpath")
|
||||||
" assuming cygwin
|
" assuming cygwin
|
||||||
@@ -326,7 +333,7 @@ fun! tar#Read(fname)
|
|||||||
elseif fname =~ '\.bz3$' && executable("bz3cat")
|
elseif fname =~ '\.bz3$' && executable("bz3cat")
|
||||||
let decmp= "|bz3cat"
|
let decmp= "|bz3cat"
|
||||||
let doro = 1
|
let doro = 1
|
||||||
elseif fname =~ '\.t\=gz$' && executable("zcat")
|
elseif fname =~ '\.t\=gz$' && executable("zcat")
|
||||||
let decmp= "|zcat"
|
let decmp= "|zcat"
|
||||||
let doro = 1
|
let doro = 1
|
||||||
elseif fname =~ '\.lzma$' && executable("lzcat")
|
elseif fname =~ '\.lzma$' && executable("lzcat")
|
||||||
@@ -349,66 +356,72 @@ fun! tar#Read(fname)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if exists("g:tar_secure")
|
||||||
|
let tar_secure= " -- "
|
||||||
|
else
|
||||||
|
let tar_secure= " "
|
||||||
|
endif
|
||||||
|
|
||||||
if tarfile =~# '\.bz2$'
|
if tarfile =~# '\.bz2$'
|
||||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif tarfile =~# '\.bz3$'
|
elseif tarfile =~# '\.bz3$'
|
||||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif tarfile =~# '\.\(gz\)$'
|
elseif tarfile =~# '\.\(gz\)$'
|
||||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
|
elseif tarfile =~# '\(\.tgz\|\.tbz\|\.txz\)'
|
||||||
let filekind= s:Header(tarfile)
|
if has("unix") && executable("file")
|
||||||
if filekind =~? "bzip2"
|
let filekind= system("file ".shellescape(tarfile,1))
|
||||||
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
else
|
||||||
|
let filekind= ""
|
||||||
|
endif
|
||||||
|
if filekind =~ "bzip2"
|
||||||
|
exe "sil! r! bzip2 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif filekind =~ "bzip3"
|
elseif filekind =~ "bzip3"
|
||||||
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! bzip3 -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif filekind =~? "xz"
|
elseif filekind =~ "XZ"
|
||||||
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! xz -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif filekind =~? "zstd"
|
elseif filekind =~ "Zstandard"
|
||||||
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! zstd --decompress --stdout -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif filekind =~? "gzip"
|
else
|
||||||
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! gzip -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
endif
|
endif
|
||||||
|
|
||||||
elseif tarfile =~# '\.lrp$'
|
elseif tarfile =~# '\.lrp$'
|
||||||
exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! cat -- ".shellescape(tarfile,1)." | gzip -d -c - | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif tarfile =~# '\.lzma$'
|
elseif tarfile =~# '\.lzma$'
|
||||||
exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! lzma -d -c -- ".shellescape(tarfile,1)."| ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif tarfile =~# '\.\(xz\|txz\)$'
|
elseif tarfile =~# '\.\(xz\|txz\)$'
|
||||||
exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! xz --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
elseif tarfile =~# '\.\(lz4\|tlz4\)$'
|
elseif tarfile =~# '\.\(lz4\|tlz4\)$'
|
||||||
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".g:tar_secure.shellescape(fname,1).decmp
|
exe "sil! r! lz4 --decompress --stdout -- ".shellescape(tarfile,1)." | ".g:tar_cmd." -".g:tar_readoptions." - ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
else
|
else
|
||||||
if tarfile =~ '^\s*-'
|
if tarfile =~ '^\s*-'
|
||||||
" A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
|
" A file name starting with a dash is taken as an option. Prepend ./ to avoid that.
|
||||||
let tarfile = substitute(tarfile, '-', './-', '')
|
let tarfile = substitute(tarfile, '-', './-', '')
|
||||||
endif
|
endif
|
||||||
exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".g:tar_secure.shellescape(fname,1).decmp
|
exe "silent r! ".g:tar_cmd." -".g:tar_readoptions.shellescape(tarfile,1)." ".tar_secure.shellescape(fname,1).decmp
|
||||||
exe "read ".escape_file
|
exe "read ".escape_file
|
||||||
endif
|
endif
|
||||||
if get(b:, 'leading_slash', 0)
|
|
||||||
sil g/^tar: /d
|
|
||||||
endif
|
|
||||||
|
|
||||||
redraw!
|
redraw!
|
||||||
|
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
lcd ..
|
cd ..
|
||||||
call s:Rmdir("_ZIPVIM_")
|
call s:Rmdir("_ZIPVIM_")
|
||||||
exe "lcd ".fnameescape(curdir)
|
exe "cd ".fnameescape(curdir)
|
||||||
call s:Msg('tar#Read', 'error', $"sorry, unable to open or extract {tarfile} with {fname}")
|
echohl Error | echo "***error*** (tar#Read) sorry, unable to open or extract ".tarfile." with ".fname | echohl None
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if doro
|
if doro
|
||||||
@@ -417,54 +430,40 @@ fun! tar#Read(fname)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
let b:tarfile= a:fname
|
let b:tarfile= a:fname
|
||||||
|
exe "file tarfile::".fnameescape(fname)
|
||||||
|
|
||||||
" cleanup
|
" cleanup
|
||||||
keepj sil! 0d
|
keepj sil! 0d
|
||||||
set nomod
|
set nomod
|
||||||
|
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
exe "lcd ".fnameescape(curdir)
|
|
||||||
silent exe "file tarfile::". fname->fnameescape()
|
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
" tar#Write: {{{2
|
" tar#Write: {{{2
|
||||||
fun! tar#Write(fname)
|
fun! tar#Write(fname)
|
||||||
let pwdkeep= getcwd()
|
|
||||||
let repkeep= &report
|
let repkeep= &report
|
||||||
set report=10
|
set report=10
|
||||||
|
" temporary buffer variable workaround because too fucking tired. but it works now
|
||||||
let curdir= b:curdir
|
let curdir= b:curdir
|
||||||
let tmpdir= b:tmpdir
|
let tmpdir= b:tmpdir
|
||||||
|
|
||||||
|
if !exists("g:tar_secure") && a:fname =~ '^\s*-\|\s\+-'
|
||||||
|
redraw!
|
||||||
|
echohl WarningMsg | echo '***warning*** (tar#Write) rejecting tarfile member<'.a:fname.'> because of embedded "-"'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
" sanity checks
|
" sanity checks
|
||||||
if !executable(g:tar_cmd)
|
if !executable(g:tar_cmd)
|
||||||
redraw!
|
redraw!
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
|
let tarfile = substitute(b:tarfile,'tarfile:\(.\{-}\)::.*$','\1','')
|
||||||
let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')
|
let fname = substitute(b:tarfile,'tarfile:.\{-}::\(.*\)$','\1','')
|
||||||
|
|
||||||
if get(b:, 'leading_slash', 0)
|
|
||||||
call s:Msg('tar#Write', 'error', $"sorry, not attempting to update {tarfile} with {fname}")
|
|
||||||
let &report= repkeep
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !isdirectory(fnameescape(tmpdir))
|
|
||||||
call mkdir(fnameescape(tmpdir), 'p')
|
|
||||||
endif
|
|
||||||
exe $"lcd {fnameescape(tmpdir)}"
|
|
||||||
if isdirectory("_ZIPVIM_")
|
|
||||||
call s:Rmdir("_ZIPVIM_")
|
|
||||||
endif
|
|
||||||
call mkdir("_ZIPVIM_")
|
|
||||||
lcd _ZIPVIM_
|
|
||||||
let dir = fnamemodify(fname, ':p:h')
|
|
||||||
if dir !~# '_ZIPVIM_$'
|
|
||||||
call mkdir(dir)
|
|
||||||
endif
|
|
||||||
|
|
||||||
" handle compressed archives
|
" handle compressed archives
|
||||||
if tarfile =~# '\.bz2'
|
if tarfile =~# '\.bz2'
|
||||||
call system("bzip2 -d -- ".shellescape(tarfile,0))
|
call system("bzip2 -d -- ".shellescape(tarfile,0))
|
||||||
@@ -500,10 +499,10 @@ fun! tar#Write(fname)
|
|||||||
let tarfile = substitute(tarfile,'\.lzma','','e')
|
let tarfile = substitute(tarfile,'\.lzma','','e')
|
||||||
let compress= "lzma -- ".shellescape(tarfile,0)
|
let compress= "lzma -- ".shellescape(tarfile,0)
|
||||||
endif
|
endif
|
||||||
" Note: no support for name.tar.tbz/.txz/.tgz/.tlz4/.tzst
|
|
||||||
|
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Write', 'error', $"sorry, unable to update {tarfile} with {fname}")
|
redraw!
|
||||||
|
echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".tarfile." with ".fname | echohl None
|
||||||
else
|
else
|
||||||
|
|
||||||
if fname =~ '/'
|
if fname =~ '/'
|
||||||
@@ -521,22 +520,28 @@ fun! tar#Write(fname)
|
|||||||
let tarfile = substitute(tarfile, '-', './-', '')
|
let tarfile = substitute(tarfile, '-', './-', '')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" don't overwrite a file forcefully
|
if exists("g:tar_secure")
|
||||||
exe "w ".fnameescape(fname)
|
let tar_secure= " -- "
|
||||||
|
else
|
||||||
|
let tar_secure= " "
|
||||||
|
endif
|
||||||
|
exe "w! ".fnameescape(fname)
|
||||||
if has("win32unix") && executable("cygpath")
|
if has("win32unix") && executable("cygpath")
|
||||||
let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e')
|
let tarfile = substitute(system("cygpath ".shellescape(tarfile,0)),'\n','','e')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" delete old file from tarfile
|
" delete old file from tarfile
|
||||||
" Note: BSD tar does not support --delete flag
|
call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
|
||||||
call system(g:tar_cmd." ".g:tar_delfile." ".shellescape(tarfile,0).g:tar_secure.shellescape(fname,0))
|
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Write', 'error', $"sorry, unable to update {fnameescape(tarfile)} with {fnameescape(fname)} --delete not supported?")
|
redraw!
|
||||||
|
echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
|
||||||
else
|
else
|
||||||
|
|
||||||
" update tarfile with new file
|
" update tarfile with new file
|
||||||
call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).g:tar_secure.shellescape(fname,0))
|
call system(g:tar_cmd." -".g:tar_writeoptions." ".shellescape(tarfile,0).tar_secure.shellescape(fname,0))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Write', 'error', $"sorry, unable to update {fnameescape(tarfile)} with {fnameescape(fname)}")
|
redraw!
|
||||||
|
echohl Error | echo "***error*** (tar#Write) sorry, unable to update ".fnameescape(tarfile)." with ".fnameescape(fname) | echohl None
|
||||||
elseif exists("compress")
|
elseif exists("compress")
|
||||||
call system(compress)
|
call system(compress)
|
||||||
if exists("tgz")
|
if exists("tgz")
|
||||||
@@ -562,9 +567,9 @@ fun! tar#Write(fname)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
" cleanup and restore current directory
|
" cleanup and restore current directory
|
||||||
lcd ..
|
cd ..
|
||||||
call s:Rmdir("_ZIPVIM_")
|
call s:Rmdir("_ZIPVIM_")
|
||||||
exe "lcd ".fnameescape(pwdkeep)
|
exe "cd ".fnameescape(curdir)
|
||||||
setlocal nomod
|
setlocal nomod
|
||||||
|
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
@@ -577,7 +582,6 @@ fun! tar#Diff(userfname,fname)
|
|||||||
if a:userfname != ""
|
if a:userfname != ""
|
||||||
let fname= a:userfname
|
let fname= a:userfname
|
||||||
endif
|
endif
|
||||||
exe "lcd ".fnameescape(b:tmpdir). '/_ZIPVIM_'
|
|
||||||
if filereadable(fname)
|
if filereadable(fname)
|
||||||
" sets current file (from tarball) for diff'ing
|
" sets current file (from tarball) for diff'ing
|
||||||
" splits window vertically
|
" splits window vertically
|
||||||
@@ -601,6 +605,12 @@ fun! tar#Extract()
|
|||||||
set report=10
|
set report=10
|
||||||
let fname= getline(".")
|
let fname= getline(".")
|
||||||
|
|
||||||
|
if !exists("g:tar_secure") && fname =~ '^\s*-\|\s\+-'
|
||||||
|
redraw!
|
||||||
|
echohl WarningMsg | echo '***warning*** (tar#BrowseSelect) rejecting tarfile member<'.fname.'> because of embedded "-"'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
" sanity check
|
" sanity check
|
||||||
if fname =~ '^"'
|
if fname =~ '^"'
|
||||||
let &report= repkeep
|
let &report= repkeep
|
||||||
@@ -610,20 +620,20 @@ fun! tar#Extract()
|
|||||||
let tarball = expand("%")
|
let tarball = expand("%")
|
||||||
let tarbase = substitute(tarball,'\..*$','','')
|
let tarbase = substitute(tarball,'\..*$','','')
|
||||||
|
|
||||||
let extractcmd= s:WinPath(g:tar_extractcmd)
|
let extractcmd= netrw#WinPath(g:tar_extractcmd)
|
||||||
if filereadable(tarbase.".tar")
|
if filereadable(tarbase.".tar")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ". fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
|
|
||||||
elseif filereadable(tarbase.".tgz")
|
elseif filereadable(tarbase.".tgz")
|
||||||
let extractcmd= substitute(extractcmd,"-","-z","")
|
let extractcmd= substitute(extractcmd,"-","-z","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tgz ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tgz {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tgz ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -632,7 +642,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-z","")
|
let extractcmd= substitute(extractcmd,"-","-z","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar.gz ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.gz {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.gz ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -641,7 +651,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-j","")
|
let extractcmd= substitute(extractcmd,"-","-j","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tbz ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tbz {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tbz ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -650,7 +660,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-j","")
|
let extractcmd= substitute(extractcmd,"-","-j","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar.bz2 ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz2 {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz2 ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -659,7 +669,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-j","")
|
let extractcmd= substitute(extractcmd,"-","-j","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar.bz3 ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.bz3 {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd."j ".tarbase.".tar.bz3 ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -668,7 +678,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-J","")
|
let extractcmd= substitute(extractcmd,"-","-J","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".txz ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.txz {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".txz ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -677,7 +687,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-J","")
|
let extractcmd= substitute(extractcmd,"-","-J","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar.xz ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.xz {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.xz ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -686,7 +696,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","--zstd","")
|
let extractcmd= substitute(extractcmd,"-","--zstd","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tzst ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tzst {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tzst ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -695,7 +705,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","--zstd","")
|
let extractcmd= substitute(extractcmd,"-","--zstd","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar.zst ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.zst {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.zst ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -704,7 +714,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-I lz4","")
|
let extractcmd= substitute(extractcmd,"-","-I lz4","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tlz4 ".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tlz4 {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tlz4 ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -713,7 +723,7 @@ fun! tar#Extract()
|
|||||||
let extractcmd= substitute(extractcmd,"-","-I lz4","")
|
let extractcmd= substitute(extractcmd,"-","-I lz4","")
|
||||||
call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname))
|
call system(extractcmd." ".shellescape(tarbase).".tar.lz4".shellescape(fname))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Msg('tar#Extract', 'error', $"{extractcmd} {tarbase}.tar.lz4 {fname}: failed!")
|
echohl Error | echo "***error*** ".extractcmd." ".tarbase.".tar.lz4 ".fname.": failed!" | echohl NONE
|
||||||
else
|
else
|
||||||
echo "***note*** successfully extracted ".fname
|
echo "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
@@ -726,50 +736,15 @@ endfun
|
|||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
" s:Rmdir: {{{2
|
" s:Rmdir: {{{2
|
||||||
fun! s:Rmdir(fname)
|
fun! s:Rmdir(fname)
|
||||||
call delete(a:fname, 'rf')
|
if has("unix")
|
||||||
endfun
|
call system("/bin/rm -rf -- ".shellescape(a:fname,0))
|
||||||
|
elseif has("win32") || has("win95") || has("win64") || has("win16")
|
||||||
" s:FileHeader: {{{2
|
if &shell =~? "sh$"
|
||||||
fun! s:Header(fname)
|
call system("/bin/rm -rf -- ".shellescape(a:fname,0))
|
||||||
let header= readblob(a:fname, 0, 6)
|
else
|
||||||
" Nvim: see https://github.com/neovim/neovim/pull/34968
|
call system("del /S ".shellescape(a:fname,0))
|
||||||
if header[0:2] == 0z425A68 " bzip2 header
|
endif
|
||||||
return "bzip2"
|
|
||||||
elseif header[0:2] == 0z425A33 " bzip3 header
|
|
||||||
return "bzip3"
|
|
||||||
elseif header == 0zFD377A58.5A00 " xz header
|
|
||||||
return "xz"
|
|
||||||
elseif header[0:3] == 0z28B52FFD " zstd header
|
|
||||||
return "zstd"
|
|
||||||
elseif header[0:3] == 0z04224D18 " lz4 header
|
|
||||||
return "lz4"
|
|
||||||
elseif (header[0:1] == 0z1F9D ||
|
|
||||||
\ header[0:1] == 0z1F8B ||
|
|
||||||
\ header[0:1] == 0z1F9E ||
|
|
||||||
\ header[0:1] == 0z1FA0 ||
|
|
||||||
\ header[0:1] == 0z1F1E)
|
|
||||||
return "gzip"
|
|
||||||
endif
|
endif
|
||||||
return "unknown"
|
|
||||||
endfun
|
|
||||||
|
|
||||||
" ---------------------------------------------------------------------
|
|
||||||
" s:WinPath: {{{2
|
|
||||||
fun! s:WinPath(path)
|
|
||||||
if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && has("win32")
|
|
||||||
" remove cygdrive prefix, if present
|
|
||||||
let path = substitute(a:path, '/cygdrive/\(.\)', '\1:', '')
|
|
||||||
" remove trailing slash (Win95)
|
|
||||||
let path = substitute(path, '\(\\\|/\)$', '', 'g')
|
|
||||||
" remove escaped spaces
|
|
||||||
let path = substitute(path, '\ ', ' ', 'g')
|
|
||||||
" convert slashes to backslashes
|
|
||||||
let path = substitute(path, '/', '\', 'g')
|
|
||||||
else
|
|
||||||
let path = a:path
|
|
||||||
endif
|
|
||||||
|
|
||||||
return path
|
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
" =====================================================================
|
" =====================================================================
|
||||||
|
@@ -77,6 +77,46 @@ function! tutor#TutorFolds()
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Marks: {{{1
|
||||||
|
|
||||||
|
function! tutor#ApplyMarks()
|
||||||
|
hi! link tutorExpect Special
|
||||||
|
if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
|
||||||
|
let b:tutor_sign_id = 1
|
||||||
|
for expct in keys(b:tutor_metadata['expect'])
|
||||||
|
let lnum = eval(expct)
|
||||||
|
call matchaddpos('tutorExpect', [lnum])
|
||||||
|
call tutor#CheckLine(lnum)
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! tutor#ApplyMarksOnChanged()
|
||||||
|
if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
|
||||||
|
let lnum = line('.')
|
||||||
|
if index(keys(b:tutor_metadata['expect']), string(lnum)) > -1
|
||||||
|
call tutor#CheckLine(lnum)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! tutor#CheckLine(line)
|
||||||
|
if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
|
||||||
|
let bufn = bufnr('%')
|
||||||
|
let ctext = getline(a:line)
|
||||||
|
let signs = sign_getplaced(bufn, {'lnum': a:line})[0].signs
|
||||||
|
if !empty(signs)
|
||||||
|
call sign_unplace('', {'id': signs[0].id})
|
||||||
|
endif
|
||||||
|
if b:tutor_metadata['expect'][string(a:line)] == -1 || ctext ==# b:tutor_metadata['expect'][string(a:line)]
|
||||||
|
exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorok buffer=".bufn
|
||||||
|
else
|
||||||
|
exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorbad buffer=".bufn
|
||||||
|
endif
|
||||||
|
let b:tutor_sign_id+=1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Tutor Cmd: {{{1
|
" Tutor Cmd: {{{1
|
||||||
|
|
||||||
function! s:Locale()
|
function! s:Locale()
|
||||||
@@ -203,9 +243,9 @@ function! tutor#EnableInteractive(enable)
|
|||||||
setlocal buftype=nofile
|
setlocal buftype=nofile
|
||||||
setlocal concealcursor+=inv
|
setlocal concealcursor+=inv
|
||||||
setlocal conceallevel=2
|
setlocal conceallevel=2
|
||||||
lua require('nvim.tutor').apply_marks()
|
call tutor#ApplyMarks()
|
||||||
augroup tutor_interactive
|
augroup tutor_interactive
|
||||||
autocmd! TextChanged,TextChangedI <buffer> lua require('nvim.tutor').apply_marks_on_changed()
|
autocmd! TextChanged,TextChangedI <buffer> call tutor#ApplyMarksOnChanged()
|
||||||
augroup END
|
augroup END
|
||||||
else
|
else
|
||||||
setlocal buftype<
|
setlocal buftype<
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
" 2024 Aug 18 by Vim Project: correctly handle special globbing chars
|
" 2024 Aug 18 by Vim Project: correctly handle special globbing chars
|
||||||
" 2024 Aug 21 by Vim Project: simplify condition to detect MS-Windows
|
" 2024 Aug 21 by Vim Project: simplify condition to detect MS-Windows
|
||||||
" 2025 Mar 11 by Vim Project: handle filenames with leading '-' correctly
|
" 2025 Mar 11 by Vim Project: handle filenames with leading '-' correctly
|
||||||
" 2025 Jul 12 by Vim Project: drop ../ on write to prevent path traversal attacks
|
|
||||||
" License: Vim License (see vim's :help license)
|
" License: Vim License (see vim's :help license)
|
||||||
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
|
" Copyright: Copyright (C) 2005-2019 Charles E. Campbell {{{1
|
||||||
" Permission is hereby granted to use and distribute this code,
|
" Permission is hereby granted to use and distribute this code,
|
||||||
@@ -72,9 +71,8 @@ fun! s:Mess(group, msg)
|
|||||||
echohl Normal
|
echohl Normal
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
if !has('nvim-0.10') && v:version < 901
|
if v:version < 702
|
||||||
" required for defer
|
call s:Mess('WarningMsg', "***warning*** this version of zip needs vim 7.2 or later")
|
||||||
call s:Mess('WarningMsg', "***warning*** this version of zip needs vim 9.1 or later")
|
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
" sanity checks
|
" sanity checks
|
||||||
@@ -237,62 +235,59 @@ endfun
|
|||||||
" zip#Write: {{{2
|
" zip#Write: {{{2
|
||||||
fun! zip#Write(fname)
|
fun! zip#Write(fname)
|
||||||
let dict = s:SetSaneOpts()
|
let dict = s:SetSaneOpts()
|
||||||
let need_rename = 0
|
|
||||||
defer s:RestoreOpts(dict)
|
defer s:RestoreOpts(dict)
|
||||||
|
|
||||||
" sanity checks
|
" sanity checks
|
||||||
if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
|
if !executable(substitute(g:zip_zipcmd,'\s\+.*$','',''))
|
||||||
call s:Mess('Error', "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program")
|
call s:Mess('Error', "***error*** (zip#Write) sorry, your system doesn't appear to have the ".g:zip_zipcmd." program")
|
||||||
return
|
return
|
||||||
|
endif
|
||||||
|
if !exists("*mkdir")
|
||||||
|
call s:Mess('Error', "***error*** (zip#Write) sorry, mkdir() doesn't work on your system")
|
||||||
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let curdir= getcwd()
|
let curdir= getcwd()
|
||||||
let tmpdir= tempname()
|
let tmpdir= tempname()
|
||||||
if tmpdir =~ '\.'
|
if tmpdir =~ '\.'
|
||||||
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
let tmpdir= substitute(tmpdir,'\.[^.]*$','','e')
|
||||||
endif
|
endif
|
||||||
call mkdir(tmpdir,"p")
|
call mkdir(tmpdir,"p")
|
||||||
|
|
||||||
" attempt to change to the indicated directory
|
" attempt to change to the indicated directory
|
||||||
if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
|
if s:ChgDir(tmpdir,s:ERROR,"(zip#Write) cannot cd to temporary directory")
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" place temporary files under .../_ZIPVIM_/
|
" place temporary files under .../_ZIPVIM_/
|
||||||
if isdirectory("_ZIPVIM_")
|
if isdirectory("_ZIPVIM_")
|
||||||
call delete("_ZIPVIM_", "rf")
|
call delete("_ZIPVIM_", "rf")
|
||||||
endif
|
endif
|
||||||
call mkdir("_ZIPVIM_")
|
call mkdir("_ZIPVIM_")
|
||||||
cd _ZIPVIM_
|
cd _ZIPVIM_
|
||||||
|
|
||||||
if has("unix")
|
if has("unix")
|
||||||
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
let zipfile = substitute(a:fname,'zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||||
let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
|
let fname = substitute(a:fname,'zipfile://.\{-}::\([^\\].*\)$','\1','')
|
||||||
else
|
else
|
||||||
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
let zipfile = substitute(a:fname,'^.\{-}zipfile://\(.\{-}\)::[^\\].*$','\1','')
|
||||||
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
|
let fname = substitute(a:fname,'^.\{-}zipfile://.\{-}::\([^\\].*\)$','\1','')
|
||||||
endif
|
|
||||||
if fname =~ '^[.]\{1,2}/'
|
|
||||||
call system(g:zip_zipcmd." -d ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
|
|
||||||
let fname = fname->substitute('^\([.]\{1,2}/\)\+', '', 'g')
|
|
||||||
let need_rename = 1
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if fname =~ '/'
|
if fname =~ '/'
|
||||||
let dirpath = substitute(fname,'/[^/]\+$','','e')
|
let dirpath = substitute(fname,'/[^/]\+$','','e')
|
||||||
if has("win32unix") && executable("cygpath")
|
if has("win32unix") && executable("cygpath")
|
||||||
let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
|
let dirpath = substitute(system("cygpath ".s:Escape(dirpath,0)),'\n','','e')
|
||||||
endif
|
endif
|
||||||
call mkdir(dirpath,"p")
|
call mkdir(dirpath,"p")
|
||||||
endif
|
endif
|
||||||
if zipfile !~ '/'
|
if zipfile !~ '/'
|
||||||
let zipfile= curdir.'/'.zipfile
|
let zipfile= curdir.'/'.zipfile
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" don't overwrite files forcefully
|
exe "w! ".fnameescape(fname)
|
||||||
exe "w ".fnameescape(fname)
|
|
||||||
if has("win32unix") && executable("cygpath")
|
if has("win32unix") && executable("cygpath")
|
||||||
let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
|
let zipfile = substitute(system("cygpath ".s:Escape(zipfile,0)),'\n','','e')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
|
if (has("win32") || has("win95") || has("win64") || has("win16")) && &shell !~? 'sh$'
|
||||||
@@ -301,24 +296,21 @@ fun! zip#Write(fname)
|
|||||||
|
|
||||||
call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
|
call system(g:zip_zipcmd." -u ".s:Escape(fnamemodify(zipfile,":p"),0)." ".s:Escape(fname,0))
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Mess('Error', "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname)
|
call s:Mess('Error', "***error*** (zip#Write) sorry, unable to update ".zipfile." with ".fname)
|
||||||
|
|
||||||
elseif s:zipfile_{winnr()} =~ '^\a\+://'
|
elseif s:zipfile_{winnr()} =~ '^\a\+://'
|
||||||
" support writing zipfiles across a network
|
" support writing zipfiles across a network
|
||||||
let netzipfile= s:zipfile_{winnr()}
|
let netzipfile= s:zipfile_{winnr()}
|
||||||
1split|enew
|
1split|enew
|
||||||
let binkeep= &binary
|
let binkeep= &binary
|
||||||
let eikeep = &ei
|
let eikeep = &ei
|
||||||
set binary ei=all
|
set binary ei=all
|
||||||
exe "noswapfile e! ".fnameescape(zipfile)
|
exe "noswapfile e! ".fnameescape(zipfile)
|
||||||
call netrw#NetWrite(netzipfile)
|
call netrw#NetWrite(netzipfile)
|
||||||
let &ei = eikeep
|
let &ei = eikeep
|
||||||
let &binary = binkeep
|
let &binary = binkeep
|
||||||
q!
|
q!
|
||||||
unlet s:zipfile_{winnr()}
|
unlet s:zipfile_{winnr()}
|
||||||
elseif need_rename
|
|
||||||
exe $"sil keepalt file {fnameescape($"zipfile://{zipfile}::{fname}")}"
|
|
||||||
call s:Mess('Warning', "***error*** (zip#Browse) Path Traversal Attack detected, dropping relative path")
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" cleanup and restore current directory
|
" cleanup and restore current directory
|
||||||
@@ -327,6 +319,7 @@ fun! zip#Write(fname)
|
|||||||
call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
|
call s:ChgDir(curdir,s:WARNING,"(zip#Write) unable to return to ".curdir."!")
|
||||||
call delete(tmpdir, "rf")
|
call delete(tmpdir, "rf")
|
||||||
setlocal nomod
|
setlocal nomod
|
||||||
|
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
@@ -339,18 +332,15 @@ fun! zip#Extract()
|
|||||||
|
|
||||||
" sanity check
|
" sanity check
|
||||||
if fname =~ '^"'
|
if fname =~ '^"'
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
if fname =~ '/$'
|
if fname =~ '/$'
|
||||||
call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory")
|
call s:Mess('Error', "***error*** (zip#Extract) Please specify a file, not a directory")
|
||||||
return
|
return
|
||||||
elseif fname =~ '^[.]\?[.]/'
|
|
||||||
call s:Mess('Error', "***error*** (zip#Browse) Path Traversal Attack detected, not extracting!")
|
|
||||||
return
|
|
||||||
endif
|
endif
|
||||||
if filereadable(fname)
|
if filereadable(fname)
|
||||||
call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!")
|
call s:Mess('Error', "***error*** (zip#Extract) <" .. fname .."> already exists in directory, not overwriting!")
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
let target = fname->substitute('\[', '[[]', 'g')
|
let target = fname->substitute('\[', '[[]', 'g')
|
||||||
" unzip 6.0 does not support -- to denote end-of-arguments
|
" unzip 6.0 does not support -- to denote end-of-arguments
|
||||||
@@ -372,12 +362,13 @@ fun! zip#Extract()
|
|||||||
" extract the file mentioned under the cursor
|
" extract the file mentioned under the cursor
|
||||||
call system($"{g:zip_extractcmd} -o {shellescape(b:zipfile)} {target}")
|
call system($"{g:zip_extractcmd} -o {shellescape(b:zipfile)} {target}")
|
||||||
if v:shell_error != 0
|
if v:shell_error != 0
|
||||||
call s:Mess('Error', "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!")
|
call s:Mess('Error', "***error*** ".g:zip_extractcmd." ".b:zipfile." ".fname.": failed!")
|
||||||
elseif !filereadable(fname)
|
elseif !filereadable(fname)
|
||||||
call s:Mess('Error', "***error*** attempted to extract ".fname." but it doesn't appear to be present!")
|
call s:Mess('Error', "***error*** attempted to extract ".fname." but it doesn't appear to be present!")
|
||||||
else
|
else
|
||||||
echomsg "***note*** successfully extracted ".fname
|
echomsg "***note*** successfully extracted ".fname
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
" ---------------------------------------------------------------------
|
" ---------------------------------------------------------------------
|
||||||
|
@@ -47,7 +47,6 @@ hi('WildMenu', { fg = 'Black', bg = 'Yellow', ctermfg = 'Black', cterm
|
|||||||
hi('VertSplit', { link = 'Normal' })
|
hi('VertSplit', { link = 'Normal' })
|
||||||
hi('WinSeparator', { link = 'VertSplit' })
|
hi('WinSeparator', { link = 'VertSplit' })
|
||||||
hi('WinBarNC', { link = 'WinBar' })
|
hi('WinBarNC', { link = 'WinBar' })
|
||||||
hi('DiffTextAdd', { link = 'DiffText' })
|
|
||||||
hi('EndOfBuffer', { link = 'NonText' })
|
hi('EndOfBuffer', { link = 'NonText' })
|
||||||
hi('LineNrAbove', { link = 'LineNr' })
|
hi('LineNrAbove', { link = 'LineNr' })
|
||||||
hi('LineNrBelow', { link = 'LineNr' })
|
hi('LineNrBelow', { link = 'LineNr' })
|
||||||
@@ -62,8 +61,6 @@ hi('PmenuMatchSel', { link = 'PmenuSel' })
|
|||||||
hi('PmenuExtra', { link = 'Pmenu' })
|
hi('PmenuExtra', { link = 'Pmenu' })
|
||||||
hi('PmenuExtraSel', { link = 'PmenuSel' })
|
hi('PmenuExtraSel', { link = 'PmenuSel' })
|
||||||
hi('ComplMatchIns', {})
|
hi('ComplMatchIns', {})
|
||||||
hi('ComplHint', { link = 'NonText' })
|
|
||||||
hi('ComplHintMore', { link = 'MoreMsg' })
|
|
||||||
hi('Substitute', { link = 'Search' })
|
hi('Substitute', { link = 'Search' })
|
||||||
hi('Whitespace', { link = 'NonText' })
|
hi('Whitespace', { link = 'NonText' })
|
||||||
hi('MsgSeparator', { link = 'StatusLine' })
|
hi('MsgSeparator', { link = 'StatusLine' })
|
||||||
@@ -136,7 +133,6 @@ hi('DiagnosticDeprecated', { sp = 'Red', strikethrough = true, cterm =
|
|||||||
hi('DiagnosticUnnecessary', { link = 'Comment' })
|
hi('DiagnosticUnnecessary', { link = 'Comment' })
|
||||||
hi('LspInlayHint', { link = 'NonText' })
|
hi('LspInlayHint', { link = 'NonText' })
|
||||||
hi('SnippetTabstop', { link = 'Visual' })
|
hi('SnippetTabstop', { link = 'Visual' })
|
||||||
hi('SnippetTabstopActive', { link = 'SnippetTabstop' })
|
|
||||||
|
|
||||||
-- Text
|
-- Text
|
||||||
hi('@markup.raw', { link = 'Comment' })
|
hi('@markup.raw', { link = 'Comment' })
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
" Vim compiler file
|
|
||||||
" Language: Gleam
|
|
||||||
" Maintainer: Kirill Morozov <kirill@robotix.pro>
|
|
||||||
" Based On: https://github.com/gleam-lang/gleam.vim
|
|
||||||
" Last Change: 2025 Apr 21
|
|
||||||
|
|
||||||
if exists('current_compiler')
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
let current_compiler = "gleam_build"
|
|
||||||
|
|
||||||
CompilerSet makeprg=gleam\ build
|
|
||||||
|
|
||||||
" Example error message:
|
|
||||||
"
|
|
||||||
" error: Unknown variable
|
|
||||||
" ┌─ /home/michael/root/projects/tutorials/gleam/try/code/src/main.gleam:19:18
|
|
||||||
" │
|
|
||||||
" 19 │ Ok(tuple(name, spot))
|
|
||||||
" │ ^^^^ did you mean `sport`?
|
|
||||||
"
|
|
||||||
" The name `spot` is not in scope here.
|
|
||||||
CompilerSet errorformat=%Eerror:\ %m,%Wwarning:\ %m,%C\ %#┌─%#\ %f:%l:%c\ %#-%#
|
|
||||||
|
|
||||||
" vim: sw=2 sts=2 et
|
|
@@ -2,7 +2,6 @@
|
|||||||
" Compiler: Pandoc
|
" Compiler: Pandoc
|
||||||
" Maintainer: Konfekt
|
" Maintainer: Konfekt
|
||||||
" Last Change: 2024 Nov 19
|
" Last Change: 2024 Nov 19
|
||||||
" 2025 May 15 Update the title regex for CompilerSet #17321
|
|
||||||
"
|
"
|
||||||
" Expects output file extension, say `:make html` or `:make pdf`.
|
" Expects output file extension, say `:make html` or `:make pdf`.
|
||||||
" Passes additional arguments to pandoc, say `:make html --self-contained`.
|
" Passes additional arguments to pandoc, say `:make html --self-contained`.
|
||||||
@@ -52,7 +51,7 @@ endfunction
|
|||||||
|
|
||||||
execute 'CompilerSet makeprg=pandoc'..escape(
|
execute 'CompilerSet makeprg=pandoc'..escape(
|
||||||
\ ' --standalone'..
|
\ ' --standalone'..
|
||||||
\ (s:PandocFiletype(&filetype) ==# 'markdown' && (getline(1) =~# '^%\s\+\S\+' || (search('^title:\s\+\S\+', 'cnw') > 0)) ?
|
\ (s:PandocFiletype(&filetype) ==# 'markdown' && (getline(1) =~# '^%\s\+\S\+' || (search('^title:\s+\S+', 'cnw') > 0)) ?
|
||||||
\ '' : ' --metadata title=%:t:r:S')..
|
\ '' : ' --metadata title=%:t:r:S')..
|
||||||
\ ' '..s:PandocLang()..
|
\ ' '..s:PandocLang()..
|
||||||
\ ' --from='..s:PandocFiletype(&filetype)..
|
\ ' --from='..s:PandocFiletype(&filetype)..
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
" Vim compiler file
|
|
||||||
" Compiler: PHPStan
|
|
||||||
" Maintainer: Dietrich Moerman <dietrich.moerman@gmail.com>
|
|
||||||
" Last Change: 2025 Jul 17
|
|
||||||
|
|
||||||
if exists("current_compiler")
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
let current_compiler = "phpstan"
|
|
||||||
|
|
||||||
CompilerSet makeprg=composer\ exec\ --\ phpstan\ analyse\ -v\ --no-progress\ --error-format=raw
|
|
||||||
CompilerSet errorformat=%f:%l:%m,%-G%.%#
|
|
3264
runtime/doc/api.txt
3264
runtime/doc/api.txt
File diff suppressed because it is too large
Load Diff
@@ -73,16 +73,11 @@ Or use `:execute`: >
|
|||||||
Note that special characters (e.g., "%", "<cword>") in the ":autocmd"
|
Note that special characters (e.g., "%", "<cword>") in the ":autocmd"
|
||||||
arguments are not expanded when the autocommand is defined. These will be
|
arguments are not expanded when the autocommand is defined. These will be
|
||||||
expanded when the Event is recognized, and the {cmd} is executed. The only
|
expanded when the Event is recognized, and the {cmd} is executed. The only
|
||||||
exception is that "<sfile>" (unlike "<script>") is expanded when the autocmd
|
exception is that "<sfile>" is expanded when the autocmd is defined. Example:
|
||||||
is defined. Example:
|
|
||||||
>
|
>
|
||||||
:au BufNewFile,BufRead *.html so <sfile>:h/html.vim
|
:au BufNewFile,BufRead *.html so <sfile>:h/html.vim
|
||||||
|
|
||||||
Here Vim expands <sfile> to the name of the file containing this line.
|
Here Vim expands <sfile> to the name of the file containing this line.
|
||||||
However, <sfile> works differently in a function, in which case it's better to
|
|
||||||
use `:execute` with <script> to achieve the same purpose:
|
|
||||||
>
|
|
||||||
:exe $'au BufNewFile,BufRead *.html so {expand("<script>:h")}/html.vim'
|
|
||||||
|
|
||||||
`:autocmd` adds to the list of autocommands regardless of whether they are
|
`:autocmd` adds to the list of autocommands regardless of whether they are
|
||||||
already present. When your .vimrc file is sourced twice, the autocommands
|
already present. When your .vimrc file is sourced twice, the autocommands
|
||||||
@@ -262,7 +257,7 @@ BufLeave Before leaving to another buffer. Also when
|
|||||||
Not used for ":qa" or ":q" when exiting Vim.
|
Not used for ":qa" or ":q" when exiting Vim.
|
||||||
*BufModifiedSet*
|
*BufModifiedSet*
|
||||||
BufModifiedSet After the `'modified'` value of a buffer has
|
BufModifiedSet After the `'modified'` value of a buffer has
|
||||||
been changed. Special-case of |OptionSet|.
|
been changed.
|
||||||
*BufNew*
|
*BufNew*
|
||||||
BufNew After creating a new buffer (except during
|
BufNew After creating a new buffer (except during
|
||||||
startup, see |VimEnter|) or renaming an
|
startup, see |VimEnter|) or renaming an
|
||||||
@@ -306,7 +301,6 @@ BufUnload Before unloading a buffer, when the text in
|
|||||||
going to exit.
|
going to exit.
|
||||||
NOTE: Current buffer "%" is not the target
|
NOTE: Current buffer "%" is not the target
|
||||||
buffer "<afile>", "<abuf>". |<buffer=abuf>|
|
buffer "<afile>", "<abuf>". |<buffer=abuf>|
|
||||||
*E1546*
|
|
||||||
Do not switch buffers or windows!
|
Do not switch buffers or windows!
|
||||||
Not triggered when exiting and v:dying is 2 or
|
Not triggered when exiting and v:dying is 2 or
|
||||||
more.
|
more.
|
||||||
@@ -350,8 +344,7 @@ BufWriteCmd Before writing the whole buffer to a file.
|
|||||||
The buffer contents should not be changed.
|
The buffer contents should not be changed.
|
||||||
When the command resets 'modified' the undo
|
When the command resets 'modified' the undo
|
||||||
information is adjusted to mark older undo
|
information is adjusted to mark older undo
|
||||||
states as 'modified', like |:write| does. Use
|
states as 'modified', like |:write| does.
|
||||||
the |'[| and |']| marks for the range of lines.
|
|
||||||
|Cmd-event|
|
|Cmd-event|
|
||||||
*BufWritePost*
|
*BufWritePost*
|
||||||
BufWritePost After writing the whole buffer to a file
|
BufWritePost After writing the whole buffer to a file
|
||||||
@@ -407,16 +400,6 @@ CmdlineLeave Before leaving the command-line (including
|
|||||||
Note: `abort` can only be changed from false
|
Note: `abort` can only be changed from false
|
||||||
to true: cannot execute an already aborted
|
to true: cannot execute an already aborted
|
||||||
cmdline by changing it to false.
|
cmdline by changing it to false.
|
||||||
*CmdlineLeavePre*
|
|
||||||
CmdlineLeavePre Just before leaving the command line, and
|
|
||||||
before |CmdlineLeave|. Useful for capturing
|
|
||||||
completion info with |cmdcomplete_info()|, as
|
|
||||||
this information is cleared before
|
|
||||||
|CmdlineLeave| is triggered. Triggered for
|
|
||||||
non-interactive use of ":" in a mapping, but
|
|
||||||
not when using |<Cmd>|. Also triggered when
|
|
||||||
abandoning the command line by typing CTRL-C
|
|
||||||
or <Esc>. <afile> is set to |cmdline-char|.
|
|
||||||
*CmdwinEnter*
|
*CmdwinEnter*
|
||||||
CmdwinEnter After entering the command-line window.
|
CmdwinEnter After entering the command-line window.
|
||||||
Useful for setting options specifically for
|
Useful for setting options specifically for
|
||||||
@@ -494,16 +477,27 @@ CompleteDone After Insert mode completion is done. Either
|
|||||||
- "accept": completion was
|
- "accept": completion was
|
||||||
accepted by |complete_CTRL-Y|.
|
accepted by |complete_CTRL-Y|.
|
||||||
- "cancel": completion was
|
- "cancel": completion was
|
||||||
stopped by |complete_CTRL-E|.
|
stopped by |complete_CTRL-E.
|
||||||
- "discard": completion was
|
- "discard": completion was
|
||||||
abandoned for other reason.
|
abandoned for other reason.
|
||||||
|
|
||||||
*CursorHold*
|
*CursorHold*
|
||||||
CursorHold When there is no user input for 'updatetime'
|
CursorHold When the user doesn't press a key for the time
|
||||||
duration, in Normal-mode. Not triggered while
|
specified with 'updatetime'. Not triggered
|
||||||
waiting for a command argument or movement
|
until the user has pressed a key (i.e. doesn't
|
||||||
after an operator, nor while |recording|
|
fire every 'updatetime' ms if you leave Vim to
|
||||||
a macro. See |CursorHold-example|.
|
make some coffee. :) See |CursorHold-example|
|
||||||
|
for previewing tags.
|
||||||
|
This event is only triggered in Normal mode.
|
||||||
|
It is not triggered when waiting for a command
|
||||||
|
argument to be typed, or a movement after an
|
||||||
|
operator.
|
||||||
|
While recording the CursorHold event is not
|
||||||
|
triggered. |q|
|
||||||
|
*<CursorHold>*
|
||||||
|
Internally the autocommand is triggered by the
|
||||||
|
<CursorHold> key. In an expression mapping
|
||||||
|
|getchar()| may see this character.
|
||||||
|
|
||||||
Note: Interactive commands cannot be used for
|
Note: Interactive commands cannot be used for
|
||||||
this event. There is no hit-enter prompt,
|
this event. There is no hit-enter prompt,
|
||||||
@@ -654,14 +648,14 @@ FileType When the 'filetype' option has been set. The
|
|||||||
FileWriteCmd Before writing to a file, when not writing the
|
FileWriteCmd Before writing to a file, when not writing the
|
||||||
whole buffer. Should do the writing to the
|
whole buffer. Should do the writing to the
|
||||||
file. Should not change the buffer. Use the
|
file. Should not change the buffer. Use the
|
||||||
|'[| and |']| marks for the range of lines.
|
'[ and '] marks for the range of lines.
|
||||||
|Cmd-event|
|
|Cmd-event|
|
||||||
*FileWritePost*
|
*FileWritePost*
|
||||||
FileWritePost After writing to a file, when not writing the
|
FileWritePost After writing to a file, when not writing the
|
||||||
whole buffer.
|
whole buffer.
|
||||||
*FileWritePre*
|
*FileWritePre*
|
||||||
FileWritePre Before writing to a file, when not writing the
|
FileWritePre Before writing to a file, when not writing the
|
||||||
whole buffer. Use the |'[| and |']| marks for the
|
whole buffer. Use the '[ and '] marks for the
|
||||||
range of lines.
|
range of lines.
|
||||||
*FilterReadPost*
|
*FilterReadPost*
|
||||||
FilterReadPost After reading a file from a filter command.
|
FilterReadPost After reading a file from a filter command.
|
||||||
@@ -788,31 +782,6 @@ ModeChanged After changing the mode. The pattern is
|
|||||||
:au ModeChanged [vV\x16]*:* let &l:rnu = mode() =~# '^[vV\x16]'
|
:au ModeChanged [vV\x16]*:* let &l:rnu = mode() =~# '^[vV\x16]'
|
||||||
:au ModeChanged *:[vV\x16]* let &l:rnu = mode() =~# '^[vV\x16]'
|
:au ModeChanged *:[vV\x16]* let &l:rnu = mode() =~# '^[vV\x16]'
|
||||||
:au WinEnter,WinLeave * let &l:rnu = mode() =~# '^[vV\x16]'
|
:au WinEnter,WinLeave * let &l:rnu = mode() =~# '^[vV\x16]'
|
||||||
Progress *Progress*
|
|
||||||
After a progress message is created or updated via
|
|
||||||
`nvim_echo`. The pattern is matched against
|
|
||||||
title of the message. The |event-data| contains:
|
|
||||||
id: id of the message
|
|
||||||
text: text of the message
|
|
||||||
title: title of the progress message
|
|
||||||
status: status of the progress message
|
|
||||||
percent: how much progress has been
|
|
||||||
made for this progress item
|
|
||||||
Usage example:
|
|
||||||
>
|
|
||||||
vim.api.nvim_create_autocmd('Progress', {
|
|
||||||
pattern={"term"},
|
|
||||||
callback = function(ev)
|
|
||||||
print(string.format('event fired: %s', vim.inspect(ev)))
|
|
||||||
end
|
|
||||||
})
|
|
||||||
local id = vim.api.nvim_echo({{'searching...'}}, true,
|
|
||||||
{kind='progress', status='running', percent=10, title="term"})
|
|
||||||
vim.api.nvim_echo({{'searching'}}, true,
|
|
||||||
{id = id, kind='progress', status='running', percent=50, title="term"})
|
|
||||||
vim.api.nvim_echo({{'done'}}, true,
|
|
||||||
{id = id, kind='progress', status='success', percent=100, title="term"})
|
|
||||||
|
|
||||||
< *OptionSet*
|
< *OptionSet*
|
||||||
OptionSet After setting an option (except during
|
OptionSet After setting an option (except during
|
||||||
|startup|). The |autocmd-pattern| is matched
|
|startup|). The |autocmd-pattern| is matched
|
||||||
@@ -853,10 +822,6 @@ OptionSet After setting an option (except during
|
|||||||
always use |:noautocmd| to prevent triggering
|
always use |:noautocmd| to prevent triggering
|
||||||
OptionSet.
|
OptionSet.
|
||||||
|
|
||||||
Note: Not triggered by the 'modified' option;
|
|
||||||
the |BufModifiedSet| event may be used to
|
|
||||||
handle that.
|
|
||||||
|
|
||||||
Non-recursive: |:set| in the autocommand does
|
Non-recursive: |:set| in the autocommand does
|
||||||
not trigger OptionSet again.
|
not trigger OptionSet again.
|
||||||
|
|
||||||
@@ -1069,7 +1034,7 @@ TermRequest When a |:terminal| child process emits an OSC,
|
|||||||
autocommand defined without |autocmd-nested|.
|
autocommand defined without |autocmd-nested|.
|
||||||
|
|
||||||
*TermResponse*
|
*TermResponse*
|
||||||
TermResponse When Nvim receives a DA1, OSC, DCS, or APC response from
|
TermResponse When Nvim receives an OSC or DCS response from
|
||||||
the host terminal. Sets |v:termresponse|. The
|
the host terminal. Sets |v:termresponse|. The
|
||||||
|event-data| is a table with the following fields:
|
|event-data| is a table with the following fields:
|
||||||
|
|
||||||
@@ -1093,7 +1058,7 @@ TermResponse When Nvim receives a DA1, OSC, DCS, or APC response from
|
|||||||
local r, g, b = resp:match("\027%]4;1;rgb:(%w+)/(%w+)/(%w+)")
|
local r, g, b = resp:match("\027%]4;1;rgb:(%w+)/(%w+)/(%w+)")
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
vim.api.nvim_ui_send("\027]4;1;?\027\\")
|
io.stdout:write("\027]4;1;?\027\\")
|
||||||
<
|
<
|
||||||
*TextChanged*
|
*TextChanged*
|
||||||
TextChanged After a change was made to the text in the
|
TextChanged After a change was made to the text in the
|
||||||
@@ -1221,13 +1186,6 @@ WinScrolled After any window in the current tab page
|
|||||||
or changed width or height. See
|
or changed width or height. See
|
||||||
|win-scrolled-resized|.
|
|win-scrolled-resized|.
|
||||||
|
|
||||||
Note: This can not be skipped with
|
|
||||||
`:noautocmd`, because it triggers after
|
|
||||||
processing normal commands when Vim is back in
|
|
||||||
the main loop. If you want to disable this,
|
|
||||||
consider setting the 'eventignore' option
|
|
||||||
instead.
|
|
||||||
|
|
||||||
The pattern is matched against the |window-ID|
|
The pattern is matched against the |window-ID|
|
||||||
of the first window that scrolled or resized.
|
of the first window that scrolled or resized.
|
||||||
Both <amatch> and <afile> are set to the
|
Both <amatch> and <afile> are set to the
|
||||||
|
@@ -22,13 +22,13 @@ For inserting text see |insert.txt|.
|
|||||||
"dl".
|
"dl".
|
||||||
The <Del> key does not take a [count]. Instead, it
|
The <Del> key does not take a [count]. Instead, it
|
||||||
deletes the last character of the count.
|
deletes the last character of the count.
|
||||||
See 'whichwrap' for deleting a line break (join
|
See |'whichwrap'| for deleting a line break (join
|
||||||
lines).
|
lines).
|
||||||
|
|
||||||
*X* *dh*
|
*X* *dh*
|
||||||
["x]X Delete [count] characters before the cursor [into
|
["x]X Delete [count] characters before the cursor [into
|
||||||
register x] (not |linewise|). Does the same as "dh".
|
register x] (not |linewise|). Does the same as "dh".
|
||||||
Also see 'whichwrap'.
|
Also see |'whichwrap'|.
|
||||||
|
|
||||||
*d*
|
*d*
|
||||||
["x]d{motion} Delete text that {motion} moves over [into register
|
["x]d{motion} Delete text that {motion} moves over [into register
|
||||||
@@ -141,8 +141,8 @@ the 'joinspaces' option is on, these commands insert two spaces after a '.',
|
|||||||
The 'B' and 'M' flags in 'formatoptions' change the behavior for inserting
|
The 'B' and 'M' flags in 'formatoptions' change the behavior for inserting
|
||||||
spaces before and after a multibyte character |fo-table|.
|
spaces before and after a multibyte character |fo-table|.
|
||||||
|
|
||||||
The |'[| mark is set at the end of the first line that was joined, |']| at the
|
The '[ mark is set at the end of the first line that was joined, '] at the end
|
||||||
end of the resulting line.
|
of the resulting line.
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
@@ -367,7 +367,7 @@ CTRL-A Add [count] to the number or alphabetic character at
|
|||||||
*v_g_CTRL-A*
|
*v_g_CTRL-A*
|
||||||
{Visual}g CTRL-A Add [count] to the number or alphabetic character in
|
{Visual}g CTRL-A Add [count] to the number or alphabetic character in
|
||||||
the highlighted text. If several lines are
|
the highlighted text. If several lines are
|
||||||
highlighted, each one will be incremented by an
|
highlighted, each one will be incremented by an
|
||||||
additional [count] (so effectively creating a
|
additional [count] (so effectively creating a
|
||||||
[count] incrementing sequence).
|
[count] incrementing sequence).
|
||||||
For Example, if you have this list of numbers:
|
For Example, if you have this list of numbers:
|
||||||
@@ -583,9 +583,9 @@ with ".". Vim does not recognize a comment (starting with '"') after the
|
|||||||
={motion} Filter {motion} lines through the external program
|
={motion} Filter {motion} lines through the external program
|
||||||
given with the 'equalprg' option. When the 'equalprg'
|
given with the 'equalprg' option. When the 'equalprg'
|
||||||
option is empty (this is the default), use the
|
option is empty (this is the default), use the
|
||||||
internal formatting function |C-indenting| and 'lisp'.
|
internal formatting function |C-indenting| and
|
||||||
But when 'indentexpr' is not empty, it will be used
|
|'lisp'|. But when 'indentexpr' is not empty, it will
|
||||||
instead |indent-expression|.
|
be used instead |indent-expression|.
|
||||||
|
|
||||||
*==*
|
*==*
|
||||||
== Filter [count] lines like with ={motion}.
|
== Filter [count] lines like with ={motion}.
|
||||||
@@ -644,9 +644,8 @@ original user.
|
|||||||
Repeat last :substitute with same search pattern and
|
Repeat last :substitute with same search pattern and
|
||||||
substitute string, but without the same flags. You
|
substitute string, but without the same flags. You
|
||||||
may add [flags], see |:s_flags|.
|
may add [flags], see |:s_flags|.
|
||||||
Note that after `:substitute` the '&' and '#' flags
|
Note that after `:substitute` the '&' flag can't be
|
||||||
can't be used, they're recognized as a pattern
|
used, it's recognized as a pattern separator.
|
||||||
separator.
|
|
||||||
The space between `:substitute` and the 'c', 'g',
|
The space between `:substitute` and the 'c', 'g',
|
||||||
'i', 'I' and 'r' flags isn't required, but in scripts
|
'i', 'I' and 'r' flags isn't required, but in scripts
|
||||||
it's a good idea to keep it to avoid confusion.
|
it's a good idea to keep it to avoid confusion.
|
||||||
@@ -949,26 +948,22 @@ This replaces each 'E' character with a euro sign. Read more in |<Char->|.
|
|||||||
|
|
||||||
4.3 Changing tabs *change-tabs*
|
4.3 Changing tabs *change-tabs*
|
||||||
*:ret* *:retab* *:retab!*
|
*:ret* *:retab* *:retab!*
|
||||||
:[range]ret[ab][!] [-indentonly] [{new-tabstop}]
|
:[range]ret[ab][!] [new_tabstop]
|
||||||
Replace all sequences of white-space containing a
|
Replace all sequences of white-space containing a
|
||||||
<Tab> with new strings of white-space using
|
<Tab> with new strings of white-space using the new
|
||||||
{new-tabstop}. If you do not specify {new-tabstop} or
|
tabstop value given. If you do not specify a new
|
||||||
it is zero, Vim uses the current value of 'tabstop'.
|
tabstop size or it is zero, Vim uses the current value
|
||||||
|
of 'tabstop'.
|
||||||
The current value of 'tabstop' is always used to
|
The current value of 'tabstop' is always used to
|
||||||
compute the width of existing tabs.
|
compute the width of existing tabs.
|
||||||
With !, Vim also replaces strings of only normal
|
With !, Vim also replaces strings of only normal
|
||||||
spaces with tabs where appropriate.
|
spaces with tabs where appropriate.
|
||||||
With 'expandtab' on, Vim replaces all tabs with the
|
With 'expandtab' on, Vim replaces all tabs with the
|
||||||
appropriate number of spaces.
|
appropriate number of spaces.
|
||||||
This command sets 'tabstop' to {new-tabstop} and if
|
This command sets 'tabstop' to the new value given,
|
||||||
performed on the whole file, which is default, should
|
and if performed on the whole file, which is default,
|
||||||
not make any visible change.
|
should not make any visible change.
|
||||||
|
Careful: This command modifies any <Tab> characters
|
||||||
When [-indentonly] is specified, only the leading
|
|
||||||
white-space will be targeted. Any other consecutive
|
|
||||||
white-space will not be changed.
|
|
||||||
|
|
||||||
Warning: This command modifies any <Tab> characters
|
|
||||||
inside of strings in a C program. Use "\t" to avoid
|
inside of strings in a C program. Use "\t" to avoid
|
||||||
this (that's a good habit anyway).
|
this (that's a good habit anyway).
|
||||||
`:retab!` may also change a sequence of spaces by
|
`:retab!` may also change a sequence of spaces by
|
||||||
@@ -1110,11 +1105,6 @@ inside of strings can change! Also see 'softtabstop' option. >
|
|||||||
:[line]pu[t]! [x] Put the text [from register x] before [line] (default
|
:[line]pu[t]! [x] Put the text [from register x] before [line] (default
|
||||||
current line).
|
current line).
|
||||||
|
|
||||||
*:ip* *:iput*
|
|
||||||
:[line]ip[ut] [x] like |:put|, but adjust indent to the current line
|
|
||||||
|
|
||||||
:[line]ip[ut]! [x] like |:put|!, but adjust indent to the current line
|
|
||||||
|
|
||||||
["x]]p or *]p* *]<MiddleMouse>*
|
["x]]p or *]p* *]<MiddleMouse>*
|
||||||
["x]]<MiddleMouse> Like "p", but adjust the indent to the current line.
|
["x]]<MiddleMouse> Like "p", but adjust the indent to the current line.
|
||||||
Using the mouse only works when 'mouse' contains 'n'
|
Using the mouse only works when 'mouse' contains 'n'
|
||||||
@@ -1149,27 +1139,27 @@ the ":put" command, Vim always inserts the text in the next line. You can
|
|||||||
exchange two characters with the command sequence "xp". You can exchange two
|
exchange two characters with the command sequence "xp". You can exchange two
|
||||||
lines with the command sequence "ddp". You can exchange two words with the
|
lines with the command sequence "ddp". You can exchange two words with the
|
||||||
command sequence "deep" (start with the cursor in the blank space before the
|
command sequence "deep" (start with the cursor in the blank space before the
|
||||||
first word). You can use the |']| or |`]| command after the put command to
|
first word). You can use the "']" or "`]" command after the put command to
|
||||||
move the cursor to the end of the inserted text, or use |'[| or |`[| to move
|
move the cursor to the end of the inserted text, or use "'[" or "`[" to move
|
||||||
the cursor to the start.
|
the cursor to the start.
|
||||||
|
|
||||||
*put-Visual-mode*
|
*put-Visual-mode* *v_p* *v_P*
|
||||||
When using a put command like |p| or |P| in Visual mode, Vim will try to
|
When using a put command like |p| or |P| in Visual mode, Vim will try to
|
||||||
replace the selected text with the contents of the register. How this
|
replace the selected text with the contents of the register. Whether this
|
||||||
works depends on the type of selection and the text. With blockwise selection
|
works well depends on the type of selection and the type of the text in the
|
||||||
it also depends on the size of the block and whether the corners are on an
|
register. With blockwise selection it also depends on the size of the block
|
||||||
existing character. (Implementation detail: it actually works by first
|
and whether the corners are on an existing character. (Implementation detail:
|
||||||
putting the register after the selection and then deleting the selection.)
|
it actually works by first putting the register after the selection and then
|
||||||
*v_p*
|
deleting the selection.)
|
||||||
|p| in Visual mode puts text and sets the default register (unnamed,
|
With |p| the previously selected text is put in the unnamed register (and
|
||||||
selection, or clipboard) to the previously-selected text. Useful if you want
|
possibly the selection and/or clipboard). This is useful if you want to put
|
||||||
to put that text somewhere else. But you cannot repeat the same change.
|
that text somewhere else. But you cannot repeat the same change.
|
||||||
*v_P*
|
With |P| the unnamed register is not changed (and neither the selection or
|
||||||
|P| in Visual mode puts text without setting the default register. You can
|
clipboard), you can repeat the same change. But the deleted text cannot be
|
||||||
repeat the change, but the deleted text cannot be used. If you do need it you
|
used. If you do need it you can use |p| with another register. E.g., yank
|
||||||
can use |p| with another register. E.g., yank the text to copy, Visually
|
the text to copy, Visually select the text to replace and use "0p . You can
|
||||||
select the text to replace and use "0p . You can repeat this as many times as
|
repeat this as many times as you like, and the unnamed register will be
|
||||||
you like, and the unnamed register will be changed each time.
|
changed each time.
|
||||||
*blockwise-put*
|
*blockwise-put*
|
||||||
When a register contains text from one line (characterwise), using a
|
When a register contains text from one line (characterwise), using a
|
||||||
blockwise Visual selection, putting that register will paste that text
|
blockwise Visual selection, putting that register will paste that text
|
||||||
@@ -1249,18 +1239,6 @@ mapped. E.g. |%| is mapped by the matchit plugin.
|
|||||||
With each successive deletion or change, Vim shifts the previous contents
|
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
|
of register 1 into register 2, 2 into 3, and so forth, losing the previous
|
||||||
contents of register 9.
|
contents of register 9.
|
||||||
*yankring*
|
|
||||||
To also store yanks (not only deletions) in registers 1-9, try this: >lua
|
|
||||||
-- Yank-ring: store yanked text in registers 1-9.
|
|
||||||
vim.api.nvim_create_autocmd('TextYankPost', {
|
|
||||||
callback = function()
|
|
||||||
if vim.v.event.operator == 'y' then
|
|
||||||
for i = 9, 1, -1 do -- Shift all numbered registers.
|
|
||||||
vim.fn.setreg(tostring(i), vim.fn.getreg(tostring(i - 1)))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
3. Small delete register "- *quote_-* *quote-*
|
3. Small delete register "- *quote_-* *quote-*
|
||||||
This register contains text from commands that delete less than one line,
|
This register contains text from commands that delete less than one line,
|
||||||
@@ -1736,7 +1714,7 @@ B When joining lines, don't insert a space between two multibyte
|
|||||||
j Where it makes sense, remove a comment leader when joining lines. For
|
j Where it makes sense, remove a comment leader when joining lines. For
|
||||||
example, joining:
|
example, joining:
|
||||||
int i; // the index ~
|
int i; // the index ~
|
||||||
// in the list ~
|
// in the list ~
|
||||||
Becomes:
|
Becomes:
|
||||||
int i; // the index in the list ~
|
int i; // the index in the list ~
|
||||||
*fo-p*
|
*fo-p*
|
||||||
@@ -1839,7 +1817,6 @@ And a few warnings:
|
|||||||
|
|
||||||
Vim has a sorting function and a sorting command. The sorting function can be
|
Vim has a sorting function and a sorting command. The sorting function can be
|
||||||
found here: |sort()|, |uniq()|.
|
found here: |sort()|, |uniq()|.
|
||||||
Also see |:uniq|.
|
|
||||||
|
|
||||||
*:sor* *:sort*
|
*:sor* *:sort*
|
||||||
:[range]sor[t][!] [b][f][i][l][n][o][r][u][x] [/{pattern}/]
|
:[range]sor[t][!] [b][f][i][l][n][o][r][u][x] [/{pattern}/]
|
||||||
@@ -1849,7 +1826,7 @@ Also see |:uniq|.
|
|||||||
With [!] the order is reversed.
|
With [!] the order is reversed.
|
||||||
|
|
||||||
With [i] case is ignored.
|
With [i] case is ignored.
|
||||||
*:sort-l*
|
|
||||||
With [l] sort uses the current collation locale.
|
With [l] sort uses the current collation locale.
|
||||||
Implementation details: strcoll() is used to compare
|
Implementation details: strcoll() is used to compare
|
||||||
strings. See |:language| to check or set the collation
|
strings. See |:language| to check or set the collation
|
||||||
@@ -1881,14 +1858,13 @@ Also see |:uniq|.
|
|||||||
|
|
||||||
With [b] sorting is done on the first binary number in
|
With [b] sorting is done on the first binary number in
|
||||||
the line (after or inside a {pattern} match).
|
the line (after or inside a {pattern} match).
|
||||||
*:sort-u* *:sort-uniq*
|
|
||||||
With [u] (u stands for unique) only keep the first of
|
With [u] (u stands for unique) only keep the first of
|
||||||
a sequence of identical lines (ignoring case when [i]
|
a sequence of identical lines (ignoring case when [i]
|
||||||
is used). Without this flag, a sequence of identical
|
is used). Without this flag, a sequence of identical
|
||||||
lines will be kept in their original order.
|
lines will be kept in their original order.
|
||||||
Note that leading and trailing white space may cause
|
Note that leading and trailing white space may cause
|
||||||
lines to be different.
|
lines to be different.
|
||||||
When you just want to make things unique, use |:uniq|.
|
|
||||||
|
|
||||||
When /{pattern}/ is specified and there is no [r] flag
|
When /{pattern}/ is specified and there is no [r] flag
|
||||||
the text matched with {pattern} is skipped, so that
|
the text matched with {pattern} is skipped, so that
|
||||||
@@ -1935,55 +1911,4 @@ The sorting can be interrupted, but if you interrupt it too late in the
|
|||||||
process you may end up with duplicated lines. This also depends on the system
|
process you may end up with duplicated lines. This also depends on the system
|
||||||
library function used.
|
library function used.
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
8. Deduplicating text *deduplicating* *unique*
|
|
||||||
|
|
||||||
Vim has a deduplicating function and a deduplicating command. The
|
|
||||||
deduplicating function can be found here: |uniq()|.
|
|
||||||
Also see |:sort-uniq|.
|
|
||||||
|
|
||||||
*:uni* *:uniq*
|
|
||||||
:[range]uni[q][!] [i][l][r][u] [/{pattern}/]
|
|
||||||
Remove duplicate lines that are adjacent to each other
|
|
||||||
in [range]. When no range is given, all lines are
|
|
||||||
processed.
|
|
||||||
|
|
||||||
With [i] case is ignored when comparing lines.
|
|
||||||
|
|
||||||
With [l] comparison uses the current collation locale.
|
|
||||||
See |:sort-l| for more details.
|
|
||||||
|
|
||||||
With [r] comparison is done on the text that matches
|
|
||||||
/{pattern}/ instead of the full line.
|
|
||||||
|
|
||||||
With [u] only keep lines that do not repeat (i.e., are
|
|
||||||
not immediately followed by the same line).
|
|
||||||
|
|
||||||
With [!] only keep lines that are immediately followed
|
|
||||||
by a duplicate.
|
|
||||||
|
|
||||||
If both [!] and [u] are given, [u] is ignored and [!]
|
|
||||||
takes effect.
|
|
||||||
|
|
||||||
When /{pattern}/ is specified and [r] is not used, the
|
|
||||||
text matched with {pattern} is skipped and comparison
|
|
||||||
is done on what comes after the match.
|
|
||||||
'ignorecase' applies to the pattern, but 'smartcase'
|
|
||||||
is not used.
|
|
||||||
Instead of the slash any non-letter can be used.
|
|
||||||
|
|
||||||
For example, to remove adjacent duplicate lines based
|
|
||||||
on the second comma-separated field: >
|
|
||||||
:uniq /[^,]*,/
|
|
||||||
< Or to keep only unique lines ignoring the first 5
|
|
||||||
characters: >
|
|
||||||
:uniq u /.\{5}/
|
|
||||||
< If {pattern} is empty (e.g. // is used), the last
|
|
||||||
search pattern is used.
|
|
||||||
|
|
||||||
Note that leading and trailing white space may cause
|
|
||||||
lines to be considered different.
|
|
||||||
To remove all duplicates regardless of position, use
|
|
||||||
|:sort-u| or external tools.
|
|
||||||
|
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -177,85 +177,84 @@ Put this in `uppercase.vim` and run: >bash
|
|||||||
==============================================================================
|
==============================================================================
|
||||||
5. Using a prompt buffer *prompt-buffer*
|
5. Using a prompt buffer *prompt-buffer*
|
||||||
|
|
||||||
Prompt buffers provide a "prompt" interface: they are like regular buffers,
|
If you want to type input for the job in a Vim window you have a few options:
|
||||||
except only the last section of the buffer is editable, and the user can
|
- Use a normal buffer and handle all possible commands yourself.
|
||||||
"submit" the prompt by hitting Enter. Useful for implementing:
|
This will be complicated, since there are so many possible commands.
|
||||||
|
- Use a terminal window. This works well if what you type goes directly to
|
||||||
- chat UI
|
the job and the job output is directly displayed in the window.
|
||||||
- REPL or shell plugins
|
See |terminal|.
|
||||||
- advanced "picker" plugins
|
- Use a window with a prompt buffer. This works well when entering a line for
|
||||||
|
the job in Vim while displaying (possibly filtered) output from the job.
|
||||||
|
|
||||||
A prompt buffer is created by setting 'buftype' to "prompt". You would
|
A prompt buffer is created by setting 'buftype' to "prompt". You would
|
||||||
normally only do that in a newly created buffer: >vim
|
normally only do that in a newly created buffer.
|
||||||
|
|
||||||
:set buftype=prompt
|
The user can edit and enter one line of text at the very last line of the
|
||||||
|
buffer. When pressing Enter in the prompt line the callback set with
|
||||||
|
|prompt_setcallback()| is invoked. It would normally send the line to a job.
|
||||||
|
Another callback would receive the output from the job and display it in the
|
||||||
|
buffer, below the prompt (and above the next prompt).
|
||||||
|
|
||||||
The user can edit and enter text at the end of the buffer. Pressing Enter in
|
Only the text in the last line, after the prompt, is editable. The rest of the
|
||||||
the prompt section invokes the |prompt_setcallback()| callback, which is
|
buffer is not modifiable with Normal mode commands. It can be modified by
|
||||||
typically expected to process the prompt and show results by appending to the
|
calling functions, such as |append()|. Using other commands may mess up the
|
||||||
buffer. To input multiline text, use Shift+Enter to add a new line without
|
buffer.
|
||||||
submitting the prompt, or just |put| or |paste| multiline text.
|
|
||||||
|
|
||||||
Only the "prompt" part of the buffer user-editable, given by the |':| mark.
|
After setting 'buftype' to "prompt" Vim does not automatically start Insert
|
||||||
The rest of the buffer is not modifiable with Normal mode commands, though it
|
mode, use `:startinsert` if you want to enter Insert mode, so that the user
|
||||||
can be modified by functions such as |append()|. Using other commands may
|
can start typing a line.
|
||||||
mess up the buffer.
|
|
||||||
|
|
||||||
After setting `buftype=prompt`:
|
The text of the prompt can be set with the |prompt_setprompt()| function. If
|
||||||
- Nvim unsets the 'comments' option.
|
no prompt is set with |prompt_setprompt()|, "% " is used. You can get the
|
||||||
- Nvim does not automatically start Insert mode (use `:startinsert` if you
|
effective prompt text for a buffer, with |prompt_getprompt()|.
|
||||||
want to enter Insert mode)
|
|
||||||
|
|
||||||
The prompt prefix defaults to "% ", but can be set with |prompt_setprompt()|.
|
|
||||||
You can get the effective prompt prefix for with |prompt_getprompt()|.
|
|
||||||
|
|
||||||
The user can go to Normal mode and navigate through the buffer. This can be
|
The user can go to Normal mode and navigate through the buffer. This can be
|
||||||
useful to see older output or copy text.
|
useful to see older output or copy text.
|
||||||
|
|
||||||
By default during prompt insert-mode, the CTRL-W key can be used to start
|
The CTRL-W key can be used to start a window command, such as CTRL-W w to
|
||||||
a window command, such as CTRL-W w to switch to the next window. (Use
|
switch to the next window. This also works in Insert mode (use Shift-CTRL-W
|
||||||
Shift-CTRL-W to delete a word). When leaving the window Insert mode will be
|
to delete a word). When leaving the window Insert mode will be stopped. When
|
||||||
stopped. When coming back to the prompt window Insert mode will be restored.
|
coming back to the prompt window Insert mode will be restored.
|
||||||
|
|
||||||
Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
|
Any command that starts Insert mode, such as "a", "i", "A" and "I", will move
|
||||||
the cursor to the last line. "A" will move to the end of the line, "I" to the
|
the cursor to the last line. "A" will move to the end of the line, "I" to the
|
||||||
start of the line.
|
start of the line.
|
||||||
|
|
||||||
Example: start a shell in the background and prompt for the next shell
|
Here is an example for Unix. It starts a shell in the background and prompts
|
||||||
command, displaying shell output above the prompt: >vim
|
for the next shell command. Output from the shell is displayed above the
|
||||||
|
prompt. >vim
|
||||||
|
|
||||||
" Handles a line of user input.
|
" Function handling a line of text that has been typed.
|
||||||
func OnSubmit(text)
|
func TextEntered(text)
|
||||||
" Send the text to a shell with Enter appended.
|
" Send the text to a shell with Enter appended.
|
||||||
call chansend(g:shell_job, [a:text, ''])
|
call chansend(g:shell_job, [a:text, ''])
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Handles output from the shell.
|
" Function handling output from the shell: Add it above the prompt.
|
||||||
func OnOutput(channel, msg, name)
|
func GotOutput(channel, msg, name)
|
||||||
" Add shell output above the prompt.
|
call append(line("$") - 1, a:msg)
|
||||||
call append(line('$') - 1, a:msg)
|
endfunc
|
||||||
endfunc
|
|
||||||
|
|
||||||
" Handles the shell exit.
|
" Function handling the shell exits: close the window.
|
||||||
func JobExit(job, status, event)
|
func JobExit(job, status, event)
|
||||||
quit!
|
quit!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
" Start a shell in the background.
|
" Start a shell in the background.
|
||||||
let shell_job = jobstart(['/bin/sh'], #{
|
let shell_job = jobstart(["/bin/sh"], #{
|
||||||
\ on_stdout: function('OnOutput'),
|
\ on_stdout: function('GotOutput'),
|
||||||
\ on_stderr: function('OnOutput'),
|
\ on_stderr: function('GotOutput'),
|
||||||
\ on_exit: function('JobExit'),
|
\ on_exit: function('JobExit'),
|
||||||
\ })
|
\ })
|
||||||
|
|
||||||
new
|
new
|
||||||
set buftype=prompt
|
set buftype=prompt
|
||||||
let buf = bufnr('')
|
let buf = bufnr('')
|
||||||
call prompt_setcallback(buf, function('OnSubmit'))
|
call prompt_setcallback(buf, function("TextEntered"))
|
||||||
call prompt_setprompt(buf, 'shell command: ')
|
call prompt_setprompt(buf, "shell command: ")
|
||||||
|
|
||||||
" Start accepting shell commands.
|
" start accepting shell commands
|
||||||
startinsert
|
startinsert
|
||||||
<
|
<
|
||||||
|
|
||||||
vim:tw=78:ts=8:et:sw=4:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -142,16 +142,13 @@ CTRL-R {register} *c_CTRL-R* *c_<C-R>*
|
|||||||
typing CTRL-R and the second character '"' will be displayed
|
typing CTRL-R and the second character '"' will be displayed
|
||||||
to indicate that you are expected to enter the name of a
|
to indicate that you are expected to enter the name of a
|
||||||
register.
|
register.
|
||||||
When used with named or clipboard registers (A-Z,a-z,0-9,+)
|
The text is inserted as if you typed it, but mappings and
|
||||||
text is inserted literally like pasting with "p". For other
|
abbreviations are not used. Command-line completion through
|
||||||
registers, the text is inserted as if you typed it, but
|
'wildchar' is not triggered though. And characters that end
|
||||||
mappings and abbreviations are not used. Command-line
|
the command line are inserted literally (<Esc>, <CR>, <NL>,
|
||||||
completion through 'wildchar' is not triggered though. And
|
<C-C>). A <BS> or CTRL-W could still end the command line
|
||||||
characters that end the command line are inserted literally
|
though, and remaining characters will then be interpreted in
|
||||||
(<Esc>, <CR>, <NL>, <C-C>). A <BS> or CTRL-W could still end
|
another mode, which might not be what you intended.
|
||||||
the command line though, and remaining characters will then be
|
|
||||||
interpreted in another mode, which might not be what you
|
|
||||||
intended.
|
|
||||||
Special registers:
|
Special registers:
|
||||||
'"' the unnamed register, containing the text of
|
'"' the unnamed register, containing the text of
|
||||||
the last delete or yank
|
the last delete or yank
|
||||||
@@ -179,9 +176,7 @@ CTRL-R {register} *c_CTRL-R* *c_<C-R>*
|
|||||||
sure the expression evaluates to an empty
|
sure the expression evaluates to an empty
|
||||||
string. E.g.: >
|
string. E.g.: >
|
||||||
<C-R><C-R>=setcmdpos(2)[-1]<CR>
|
<C-R><C-R>=setcmdpos(2)[-1]<CR>
|
||||||
< You can use this to insert a register as
|
< See |registers| about registers.
|
||||||
typed with CTRL-R =@reg.
|
|
||||||
See |registers| about registers.
|
|
||||||
Implementation detail: When using the |expression| register
|
Implementation detail: When using the |expression| register
|
||||||
and invoking setcmdpos(), this sets the position before
|
and invoking setcmdpos(), this sets the position before
|
||||||
inserting the resulting string. Use CTRL-R CTRL-R to set the
|
inserting the resulting string. Use CTRL-R CTRL-R to set the
|
||||||
@@ -393,7 +388,7 @@ CTRL-D List names that match the pattern in front of the cursor.
|
|||||||
to the end.
|
to the end.
|
||||||
The 'wildoptions' option can be set to "tagfile" to list the
|
The 'wildoptions' option can be set to "tagfile" to list the
|
||||||
file of matching tags.
|
file of matching tags.
|
||||||
*c_CTRL-I* *c_wildchar* *c_<Tab>* */_<Tab>*
|
*c_CTRL-I* *c_wildchar* *c_<Tab>*
|
||||||
'wildchar' option
|
'wildchar' option
|
||||||
A match is done on the pattern in front of the cursor. The
|
A match is done on the pattern in front of the cursor. The
|
||||||
match (if there are several, the first match) is inserted
|
match (if there are several, the first match) is inserted
|
||||||
@@ -403,10 +398,6 @@ CTRL-D List names that match the pattern in front of the cursor.
|
|||||||
again and there were multiple matches, the next
|
again and there were multiple matches, the next
|
||||||
match is inserted. After the last match, the first is used
|
match is inserted. After the last match, the first is used
|
||||||
again (wrap around).
|
again (wrap around).
|
||||||
|
|
||||||
In search context use <CTRL-V><Tab> or "\t" to search for a
|
|
||||||
literal <Tab> instead of triggering completion.
|
|
||||||
|
|
||||||
The behavior can be changed with the 'wildmode' option.
|
The behavior can be changed with the 'wildmode' option.
|
||||||
*c_<S-Tab>*
|
*c_<S-Tab>*
|
||||||
<S-Tab> Like 'wildchar' or <Tab>, but begin with the last match and
|
<S-Tab> Like 'wildchar' or <Tab>, but begin with the last match and
|
||||||
@@ -439,7 +430,7 @@ CTRL-G When 'incsearch' is set, entering a search pattern for "/" or
|
|||||||
"?" and the current match is displayed then CTRL-G will move
|
"?" and the current match is displayed then CTRL-G will move
|
||||||
to the next match (does not take |search-offset| into account)
|
to the next match (does not take |search-offset| into account)
|
||||||
Use CTRL-T to move to the previous match. Hint: on a regular
|
Use CTRL-T to move to the previous match. Hint: on a regular
|
||||||
keyboard G is below T.
|
keyboard T is above G.
|
||||||
*c_CTRL-T* */_CTRL-T*
|
*c_CTRL-T* */_CTRL-T*
|
||||||
CTRL-T When 'incsearch' is set, entering a search pattern for "/" or
|
CTRL-T When 'incsearch' is set, entering a search pattern for "/" or
|
||||||
"?" and the current match is displayed then CTRL-T will move
|
"?" and the current match is displayed then CTRL-T will move
|
||||||
@@ -456,8 +447,6 @@ When repeating 'wildchar' or CTRL-N you cycle through the matches, eventually
|
|||||||
ending up back to what was typed. If the first match is not what you wanted,
|
ending up back to what was typed. If the first match is not what you wanted,
|
||||||
you can use <S-Tab> or CTRL-P to go straight back to what you typed.
|
you can use <S-Tab> or CTRL-P to go straight back to what you typed.
|
||||||
|
|
||||||
See also |wildtrigger()|.
|
|
||||||
|
|
||||||
The 'wildmenu' option can be set to show the matches just above the command
|
The 'wildmenu' option can be set to show the matches just above the command
|
||||||
line.
|
line.
|
||||||
|
|
||||||
@@ -575,6 +564,7 @@ that see the '"' as part of their argument:
|
|||||||
:menu (and the like)
|
:menu (and the like)
|
||||||
:mkspell
|
:mkspell
|
||||||
:normal
|
:normal
|
||||||
|
:ownsyntax
|
||||||
:popup
|
:popup
|
||||||
:registers
|
:registers
|
||||||
:return
|
:return
|
||||||
@@ -872,7 +862,7 @@ to insert special things while typing you can use the CTRL-R command. For
|
|||||||
example, "%" stands for the current file name, while CTRL-R % inserts the
|
example, "%" stands for the current file name, while CTRL-R % inserts the
|
||||||
current file name right away. See |c_CTRL-R|.
|
current file name right away. See |c_CTRL-R|.
|
||||||
|
|
||||||
Note: If you want to avoid the effects of special characters in a Vim script
|
Note: If you want to avoid the effects of special characters in a Vim script
|
||||||
you may want to use |fnameescape()|. Also see |`=|.
|
you may want to use |fnameescape()|. Also see |`=|.
|
||||||
|
|
||||||
|
|
||||||
@@ -947,6 +937,14 @@ Note: these are typed literally, they are not special keys!
|
|||||||
events).
|
events).
|
||||||
When the match is with a file name, it is expanded to the
|
When the match is with a file name, it is expanded to the
|
||||||
full path.
|
full path.
|
||||||
|
*:<sfile>* *<sfile>*
|
||||||
|
<sfile> When executing a `:source` command, is replaced with the
|
||||||
|
file name of the sourced file. *E498*
|
||||||
|
When executing a function, is replaced with the call stack,
|
||||||
|
as with <stack> (this is for backwards compatibility, using
|
||||||
|
<stack> or <script> is preferred).
|
||||||
|
Note that filename-modifiers are useless when <sfile> is
|
||||||
|
not used inside a script.
|
||||||
*:<stack>* *<stack>*
|
*:<stack>* *<stack>*
|
||||||
<stack> is replaced with the call stack, using
|
<stack> is replaced with the call stack, using
|
||||||
"function {function-name}[{lnum}]" for a function line
|
"function {function-name}[{lnum}]" for a function line
|
||||||
@@ -954,7 +952,7 @@ Note: these are typed literally, they are not special keys!
|
|||||||
".." in between items. E.g.:
|
".." in between items. E.g.:
|
||||||
"function {function-name1}[{lnum}]..{function-name2}[{lnum}]"
|
"function {function-name1}[{lnum}]..{function-name2}[{lnum}]"
|
||||||
If there is no call stack you get error *E489* .
|
If there is no call stack you get error *E489* .
|
||||||
*:<script>* *<script>* *E498*
|
*:<script>* *<script>*
|
||||||
<script> When executing a `:source` command, is replaced with the file
|
<script> When executing a `:source` command, is replaced with the file
|
||||||
name of the sourced file. When executing a function, is
|
name of the sourced file. When executing a function, is
|
||||||
replaced with the file name of the script where it is
|
replaced with the file name of the script where it is
|
||||||
@@ -973,7 +971,7 @@ Note: these are typed literally, they are not special keys!
|
|||||||
*filename-modifiers*
|
*filename-modifiers*
|
||||||
*:_%:* *::8* *::p* *::.* *::~* *::h* *::t* *::r* *::e* *::s* *::gs* *::S*
|
*:_%:* *::8* *::p* *::.* *::~* *::h* *::t* *::r* *::e* *::s* *::gs* *::S*
|
||||||
*%:8* *%:p* *%:.* *%:~* *%:h* *%:t* *%:r* *%:e* *%:s* *%:gs* *%:S*
|
*%:8* *%:p* *%:.* *%:~* *%:h* *%:t* *%:r* *%:e* *%:s* *%:gs* *%:S*
|
||||||
The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<script>",
|
The file name modifiers can be used after "%", "#", "#n", "<cfile>", "<sfile>",
|
||||||
"<afile>" or "<abuf>". They are also used with the |fnamemodify()| function.
|
"<afile>" or "<abuf>". They are also used with the |fnamemodify()| function.
|
||||||
These modifiers can be given, in this order:
|
These modifiers can be given, in this order:
|
||||||
:p Make file name a full path. Must be the first modifier. Also
|
:p Make file name a full path. Must be the first modifier. Also
|
||||||
@@ -1244,10 +1242,8 @@ Example: >
|
|||||||
:au CmdwinLeave : let &cpt = b:cpt_save
|
:au CmdwinLeave : let &cpt = b:cpt_save
|
||||||
This sets 'complete' to use completion in the current window for |i_CTRL-N|.
|
This sets 'complete' to use completion in the current window for |i_CTRL-N|.
|
||||||
Another example: >
|
Another example: >
|
||||||
:au CmdwinEnter [/\?] startinsert
|
:au CmdwinEnter [/?] startinsert
|
||||||
This will make Vim start in Insert mode in the command-line window.
|
This will make Vim start in Insert mode in the command-line window.
|
||||||
Note: The "?" needs to be escaped, as this is a |file-pattern|. See also
|
|
||||||
|cmdline-autocompletion|.
|
|
||||||
|
|
||||||
*cmdline-char* *cmdwin-char*
|
*cmdline-char* *cmdwin-char*
|
||||||
The character used for the pattern indicates the type of command-line:
|
The character used for the pattern indicates the type of command-line:
|
||||||
|
@@ -160,4 +160,5 @@ In WinDbg: choose Open Crash Dump on the File menu. Follow the instructions in
|
|||||||
Visual Studio 2017 Community Edition can be downloaded for free from:
|
Visual Studio 2017 Community Edition can be downloaded for free from:
|
||||||
https://visualstudio.microsoft.com/downloads/
|
https://visualstudio.microsoft.com/downloads/
|
||||||
|
|
||||||
|
=========================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -12,42 +12,6 @@ They should not be used in new scripts, and old scripts should be updated.
|
|||||||
==============================================================================
|
==============================================================================
|
||||||
Deprecated features
|
Deprecated features
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
DEPRECATED IN 0.12 *deprecated-0.12*
|
|
||||||
|
|
||||||
API
|
|
||||||
|
|
||||||
• todo
|
|
||||||
|
|
||||||
DIAGNOSTICS
|
|
||||||
|
|
||||||
• "float" in |vim.diagnostic.JumpOpts|. Use "on_jump" instead.
|
|
||||||
• "float" in |vim.diagnostic.Opts.Jump|. Use "on_jump" instead.
|
|
||||||
|
|
||||||
HIGHLIGHTS
|
|
||||||
|
|
||||||
• *:ownsyntax* *w:current_syntax* Use 'winhighlight' instead.
|
|
||||||
|
|
||||||
LSP
|
|
||||||
|
|
||||||
• *vim.lsp.client_is_stopped()* Use |vim.lsp.get_client_by_id()| instead.
|
|
||||||
• *vim.lsp.util.stylize_markdown()* Use |vim.treesitter.start()| with
|
|
||||||
`vim.wo.conceallevel = 2`.
|
|
||||||
• *vim.lsp.log.should_log()* Use |vim.lsp.log.set_format_func()| instead
|
|
||||||
and return `nil` to omit entries from the logfile.
|
|
||||||
• *vim.lsp.semantic_tokens.start()* Use `vim.lsp.semantic_tokens.enable(true)` instead
|
|
||||||
• *vim.lsp.semantic_tokens.stop()* Use `vim.lsp.semantic_tokens.enable(false)` instead
|
|
||||||
• *vim.lsp.set_log_level()* Use `vim.lsp.log.set_level()` instead
|
|
||||||
• *vim.lsp.get_log_path()* Use `vim.lsp.log.get_filename()` instead
|
|
||||||
|
|
||||||
LUA
|
|
||||||
|
|
||||||
• *vim.diff()* Renamed to |vim.text.diff()|
|
|
||||||
|
|
||||||
VIMSCRIPT
|
|
||||||
|
|
||||||
• todo
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
DEPRECATED IN 0.11 *deprecated-0.11*
|
DEPRECATED IN 0.11 *deprecated-0.11*
|
||||||
|
|
||||||
@@ -102,7 +66,7 @@ LUA
|
|||||||
• vim.validate(opts: table) Use form 1. See |vim.validate()|.
|
• vim.validate(opts: table) Use form 1. See |vim.validate()|.
|
||||||
|
|
||||||
VIMSCRIPT
|
VIMSCRIPT
|
||||||
• *termopen()* Use |jobstart()| with `{term: v:true}`.
|
• *termopen()* Use |jobstart() with `{term: v:true}`.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
DEPRECATED IN 0.10 *deprecated-0.10*
|
DEPRECATED IN 0.10 *deprecated-0.10*
|
||||||
@@ -334,12 +298,13 @@ UI EXTENSIONS
|
|||||||
• *term_background* Unused. The terminal background color is now detected
|
• *term_background* Unused. The terminal background color is now detected
|
||||||
by the Nvim core directly instead of the TUI.
|
by the Nvim core directly instead of the TUI.
|
||||||
|
|
||||||
VIMSCRIPT
|
VARIABLES
|
||||||
• *<sfile>* Use |<script>| or |<stack>| instead.
|
|
||||||
• *b:terminal_job_pid* Use `jobpid(&channel)` instead.
|
• *b:terminal_job_pid* Use `jobpid(&channel)` instead.
|
||||||
• *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
|
• *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
|
||||||
• Lua: `vim.bo[bufnr].channel`
|
• Lua: `vim.bo[bufnr].channel`
|
||||||
• Vimscript: `getbufvar(bufnr, '&channel')`
|
• Vimscript: `getbufvar(bufnr, '&channel')`
|
||||||
|
|
||||||
|
VIMSCRIPT
|
||||||
• *buffer_exists()* Obsolete name for |bufexists()|.
|
• *buffer_exists()* Obsolete name for |bufexists()|.
|
||||||
• *buffer_name()* Obsolete name for |bufname()|.
|
• *buffer_name()* Obsolete name for |bufname()|.
|
||||||
• *buffer_number()* Obsolete name for |bufnr()|.
|
• *buffer_number()* Obsolete name for |bufnr()|.
|
||||||
|
@@ -53,27 +53,6 @@ Other references:
|
|||||||
- https://github.com/neovim/neovim/pull/21605
|
- https://github.com/neovim/neovim/pull/21605
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
API
|
|
||||||
|
|
||||||
*dev-api-fast*
|
|
||||||
API functions and Vimscript "eval" functions may be marked as |api-fast| which
|
|
||||||
means they are safe to call in Lua callbacks and other scenarios. A functions
|
|
||||||
CANNOT be marked as "fast" if could trigger `os_breakcheck()`, which may
|
|
||||||
"yield" the current execution and start a new execution of code not expecting
|
|
||||||
this:
|
|
||||||
- accidentally recursing into a function not expecting this.
|
|
||||||
- changing (global) state without restoring it before returning to the
|
|
||||||
"yielded" callsite.
|
|
||||||
|
|
||||||
In practice, this means any code that could trigger `os_breakcheck()` cannot
|
|
||||||
be "fast". For example, commit 3940c435e405 fixed such a bug with
|
|
||||||
`nvim__get_runtime` by explicitly disallowing `os_breakcheck()` via the
|
|
||||||
`EW_NOBREAK` flag.
|
|
||||||
|
|
||||||
Common examples of non-fast code: regexp matching, wildcard expansion,
|
|
||||||
expression evaluation.
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
|
@@ -255,7 +255,8 @@ functions. >c
|
|||||||
|
|
||||||
Integration with declarations generator ~
|
Integration with declarations generator ~
|
||||||
|
|
||||||
Every C file must contain #include of the generated header file.
|
Every C file must contain #include of the generated header file, guarded by
|
||||||
|
#ifdef INCLUDE_GENERATED_DECLARATIONS.
|
||||||
|
|
||||||
Include must go after other #includes and typedefs in .c files and after
|
Include must go after other #includes and typedefs in .c files and after
|
||||||
everything else in header files. It is allowed to omit #include in a .c file
|
everything else in header files. It is allowed to omit #include in a .c file
|
||||||
@@ -271,7 +272,9 @@ contain only non-static function declarations. >c
|
|||||||
|
|
||||||
typedef int FooType;
|
typedef int FooType;
|
||||||
|
|
||||||
#include "foo.c.generated.h"
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
# include "foo.c.generated.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
…
|
…
|
||||||
|
|
||||||
@@ -281,7 +284,9 @@ contain only non-static function declarations. >c
|
|||||||
|
|
||||||
…
|
…
|
||||||
|
|
||||||
#include "foo.h.generated.h"
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
# include "foo.h.generated.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
64-bit Portability ~
|
64-bit Portability ~
|
||||||
@@ -896,8 +901,8 @@ Return Values ~
|
|||||||
|
|
||||||
Do not needlessly surround the `return` expression with parentheses.
|
Do not needlessly surround the `return` expression with parentheses.
|
||||||
|
|
||||||
Use parentheses in `return expr;` only where you would also use them in
|
Use parentheses in `return expr`; only where you would use them in `x =
|
||||||
`x = expr;`. >c
|
expr;`. >c
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
return (some_long_condition && another_condition);
|
return (some_long_condition && another_condition);
|
||||||
|
@@ -171,8 +171,8 @@ USING GDBSERVER IN TMUX
|
|||||||
Consider using a custom makefile
|
Consider using a custom makefile
|
||||||
https://github.com/neovim/neovim/blob/master/BUILD.md#custom-makefile to
|
https://github.com/neovim/neovim/blob/master/BUILD.md#custom-makefile to
|
||||||
quickly start debugging sessions using the `gdbserver` method mentioned above.
|
quickly start debugging sessions using the `gdbserver` method mentioned above.
|
||||||
This example `local.mk` will create the debugging session when you type
|
This example `local.mk` will create the debugging session when you type `make
|
||||||
`make debug`.
|
debug`.
|
||||||
>make
|
>make
|
||||||
.PHONY: dbg-start dbg-attach debug build
|
.PHONY: dbg-start dbg-attach debug build
|
||||||
|
|
||||||
|
@@ -201,7 +201,7 @@ Docstring format:
|
|||||||
- Markdown is supported.
|
- Markdown is supported.
|
||||||
- Tags are written as `[tag]()`.
|
- Tags are written as `[tag]()`.
|
||||||
- References are written as `[tag]`
|
- References are written as `[tag]`
|
||||||
- Use "```" for code samples.
|
- Use ``` for code samples.
|
||||||
Code samples can be annotated as `vim` or `lua`
|
Code samples can be annotated as `vim` or `lua`
|
||||||
|
|
||||||
Example: the help for |nvim_open_win()| is generated from a docstring defined
|
Example: the help for |nvim_open_win()| is generated from a docstring defined
|
||||||
@@ -245,7 +245,7 @@ Docstring format:
|
|||||||
- Markdown is supported.
|
- Markdown is supported.
|
||||||
- Tags are written as `[tag]()`.
|
- Tags are written as `[tag]()`.
|
||||||
- References are written as `[tag]`
|
- References are written as `[tag]`
|
||||||
- Use "```" for code samples.
|
- Use ``` for code samples.
|
||||||
Code samples can be annotated as `vim` or `lua`
|
Code samples can be annotated as `vim` or `lua`
|
||||||
- Use `@since <api-level>` to note the |api-level| when the function became
|
- Use `@since <api-level>` to note the |api-level| when the function became
|
||||||
"stable". If `<api-level>` is greater than the current stable release (or
|
"stable". If `<api-level>` is greater than the current stable release (or
|
||||||
@@ -353,7 +353,7 @@ Where possible, these patterns apply to _both_ Lua and the API:
|
|||||||
- Examples: |vim.lsp.codelens.clear()| |vim.diagnostic.enable()|
|
- Examples: |vim.lsp.codelens.clear()| |vim.diagnostic.enable()|
|
||||||
- Any function signature that accepts a callback (example: |table.foreach()|)
|
- Any function signature that accepts a callback (example: |table.foreach()|)
|
||||||
should place it as the LAST parameter (after opts), if possible (or ALWAYS
|
should place it as the LAST parameter (after opts), if possible (or ALWAYS
|
||||||
for |continuation|s——functions called exactly once).
|
for "continuation callbacks"—functions called exactly once).
|
||||||
- Improves readability by placing the less "noisy" arguments near the start.
|
- Improves readability by placing the less "noisy" arguments near the start.
|
||||||
- Consistent with luv.
|
- Consistent with luv.
|
||||||
- Useful for future async lib which transforms functions of the form
|
- Useful for future async lib which transforms functions of the form
|
||||||
@@ -426,9 +426,6 @@ Use existing common {verb} names (actions) if possible:
|
|||||||
- add: Appends or inserts into a collection
|
- add: Appends or inserts into a collection
|
||||||
- attach: Listens to something to get events from it (TODO: rename to "on"?)
|
- attach: Listens to something to get events from it (TODO: rename to "on"?)
|
||||||
- call: Calls a function
|
- call: Calls a function
|
||||||
- callback |continuation|: Function parameter (NOT a field) that
|
|
||||||
returns the result of an async function. Use the "on_…"
|
|
||||||
naming-convention for all other callbacks and event handlers.
|
|
||||||
- cancel: Cancels or dismisses an event or interaction, typically
|
- cancel: Cancels or dismisses an event or interaction, typically
|
||||||
user-initiated and without error. (Compare "abort", which
|
user-initiated and without error. (Compare "abort", which
|
||||||
cancels and signals error/failure.)
|
cancels and signals error/failure.)
|
||||||
@@ -447,12 +444,8 @@ Use existing common {verb} names (actions) if possible:
|
|||||||
- has: Checks for the presence of an item, feature, etc.
|
- has: Checks for the presence of an item, feature, etc.
|
||||||
- inspect: Presents a high-level, often interactive, view
|
- inspect: Presents a high-level, often interactive, view
|
||||||
- is_enabled: Checks if functionality is enabled.
|
- is_enabled: Checks if functionality is enabled.
|
||||||
- on_…: Handles events or async results, or registers such
|
|
||||||
a handler. |dev-name-events|
|
|
||||||
- open: Opens something (a buffer, window, …)
|
- open: Opens something (a buffer, window, …)
|
||||||
- parse: Parses something into a structured form
|
- parse: Parses something into a structured form
|
||||||
- request: Calls a remote (network, RPC) operation.
|
|
||||||
- send: Writes data or a message to a channel.
|
|
||||||
- set: Sets a thing (or group of things)
|
- set: Sets a thing (or group of things)
|
||||||
- start: Spin up a long-lived process. Prefer "enable" except when
|
- start: Spin up a long-lived process. Prefer "enable" except when
|
||||||
"start" is obviously more appropriate.
|
"start" is obviously more appropriate.
|
||||||
@@ -463,7 +456,7 @@ Do NOT use these deprecated verbs:
|
|||||||
- contains: Prefer "has".
|
- contains: Prefer "has".
|
||||||
- disable: Prefer `enable(enable: boolean)`.
|
- disable: Prefer `enable(enable: boolean)`.
|
||||||
- exit: Prefer "cancel" (or "stop" if appropriate).
|
- exit: Prefer "cancel" (or "stop" if appropriate).
|
||||||
- is_disabled: Prefer `!is_enabled()`.
|
- is_disabled: Prefer `is_enabled()`.
|
||||||
- list: Redundant with "get"
|
- list: Redundant with "get"
|
||||||
- notify: Redundant with "print", "echo"
|
- notify: Redundant with "print", "echo"
|
||||||
- show: Redundant with "print", "echo"
|
- show: Redundant with "print", "echo"
|
||||||
@@ -484,6 +477,7 @@ everywhere, not "buffer" in some places and "buf" in others.
|
|||||||
|
|
||||||
Do NOT use these deprecated nouns:
|
Do NOT use these deprecated nouns:
|
||||||
- buffer Use "buf" instead
|
- buffer Use "buf" instead
|
||||||
|
- callback Use on_foo instead
|
||||||
- command Use "cmd" instead
|
- command Use "cmd" instead
|
||||||
- window Use "win" instead
|
- window Use "win" instead
|
||||||
|
|
||||||
@@ -501,14 +495,6 @@ Use this format to name API (RPC) events: >
|
|||||||
Example: >
|
Example: >
|
||||||
nvim_buf_changedtick_event
|
nvim_buf_changedtick_event
|
||||||
<
|
<
|
||||||
*continuation*
|
|
||||||
A "continuation" is implemented as a callback function that returns the result
|
|
||||||
of an async function and is called exactly once. Often accepts `err` as the
|
|
||||||
first parameter, to avoid erroring on the main thread. Example: >
|
|
||||||
foo(…, callback: fun(err, …))
|
|
||||||
Use the name `callback` only for a continuation. All other callbacks and event
|
|
||||||
handlers should be named with the |dev-name-events| "on_…" convention.
|
|
||||||
|
|
||||||
*dev-api-name*
|
*dev-api-name*
|
||||||
Use this format to name new RPC |API| functions: >
|
Use this format to name new RPC |API| functions: >
|
||||||
nvim_{topic}_{verb}_{arbitrary-qualifiers}
|
nvim_{topic}_{verb}_{arbitrary-qualifiers}
|
||||||
@@ -682,8 +668,6 @@ External UIs are expected to implement these common features:
|
|||||||
the user).
|
the user).
|
||||||
- Support the text decorations/attributes given by |ui-event-hl_attr_define|.
|
- Support the text decorations/attributes given by |ui-event-hl_attr_define|.
|
||||||
The "url" attr should be presented as a clickable hyperlink.
|
The "url" attr should be presented as a clickable hyperlink.
|
||||||
- Handle the "restart" UI event so that |:restart| works.
|
|
||||||
- Detect capslock and show an indicator if capslock is active.
|
|
||||||
|
|
||||||
|
|
||||||
vim:tw=78:ts=8:sw=4:et:ft=help:norl:
|
vim:tw=78:ts=8:sw=4:et:ft=help:norl:
|
||||||
|
@@ -190,28 +190,6 @@ the `virtual_lines` handler with the following keymap: >lua
|
|||||||
end, { desc = 'Toggle diagnostic virtual_lines' })
|
end, { desc = 'Toggle diagnostic virtual_lines' })
|
||||||
<
|
<
|
||||||
|
|
||||||
*diagnostic-on-jump-example*
|
|
||||||
You can use the `on_jump` option from |vim.diagnostic.jump()| to show the
|
|
||||||
diagnostic that was jumped to using a specific handler. For example, the
|
|
||||||
following uses the `virtual_lines` handler when jumping to a diagnostic: >lua
|
|
||||||
|
|
||||||
local virt_lines_ns = vim.api.nvim_create_namespace 'on_diagnostic_jump'
|
|
||||||
|
|
||||||
--- @param diagnostic? vim.Diagnostic
|
|
||||||
--- @param bufnr integer
|
|
||||||
local function on_jump(diagnostic, bufnr)
|
|
||||||
if not diagnostic then return end
|
|
||||||
|
|
||||||
vim.diagnostic.show(
|
|
||||||
virt_lines_ns,
|
|
||||||
bufnr,
|
|
||||||
{ diagnostic },
|
|
||||||
{ virtual_lines = { current_line = true }, virtual_text = false }
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.diagnostic.config({ jump = { on_jump = on_jump } })
|
|
||||||
<
|
|
||||||
*diagnostic-loclist-example*
|
*diagnostic-loclist-example*
|
||||||
Whenever the |location-list| is opened, the following `show` handler will show
|
Whenever the |location-list| is opened, the following `show` handler will show
|
||||||
the most recent diagnostics: >lua
|
the most recent diagnostics: >lua
|
||||||
@@ -440,43 +418,27 @@ Example: >lua
|
|||||||
Lua module: vim.diagnostic *diagnostic-api*
|
Lua module: vim.diagnostic *diagnostic-api*
|
||||||
|
|
||||||
*vim.Diagnostic*
|
*vim.Diagnostic*
|
||||||
Extends: |vim.Diagnostic.Set|
|
|
||||||
|
|
||||||
*diagnostic-structure*
|
*diagnostic-structure*
|
||||||
|
|
||||||
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
|
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
|
||||||
0-based rows and columns). |api-indexing|
|
0-based rows and columns). |api-indexing|
|
||||||
|
|
||||||
Fields: ~
|
Fields: ~
|
||||||
• {bufnr} (`integer`) Buffer number
|
• {bufnr}? (`integer`) Buffer number
|
||||||
• {end_lnum} (`integer`) The final line of the diagnostic (0-indexed)
|
|
||||||
• {col} (`integer`) The starting column of the diagnostic
|
|
||||||
(0-indexed)
|
|
||||||
• {end_col} (`integer`) The final column of the diagnostic
|
|
||||||
(0-indexed)
|
|
||||||
• {severity} (`vim.diagnostic.Severity`) The severity of the
|
|
||||||
diagnostic |vim.diagnostic.severity|
|
|
||||||
• {namespace}? (`integer`)
|
|
||||||
|
|
||||||
*vim.Diagnostic.Set*
|
|
||||||
Diagnostics use the same indexing as the rest of the Nvim API (i.e.
|
|
||||||
0-based rows and columns). |api-indexing|
|
|
||||||
|
|
||||||
Fields: ~
|
|
||||||
• {lnum} (`integer`) The starting line of the diagnostic
|
• {lnum} (`integer`) The starting line of the diagnostic
|
||||||
(0-indexed)
|
(0-indexed)
|
||||||
• {col}? (`integer`, default: `0`) The starting column of the
|
• {end_lnum}? (`integer`) The final line of the diagnostic (0-indexed)
|
||||||
diagnostic (0-indexed)
|
• {col} (`integer`) The starting column of the diagnostic
|
||||||
• {end_lnum}? (`integer`, default: `lnum`) The final line of the
|
(0-indexed)
|
||||||
diagnostic (0-indexed)
|
• {end_col}? (`integer`) The final column of the diagnostic
|
||||||
• {end_col}? (`integer`, default: `col`) The final column of the
|
(0-indexed)
|
||||||
diagnostic (0-indexed)
|
• {severity}? (`vim.diagnostic.Severity`) The severity of the
|
||||||
• {severity}? (`vim.diagnostic.Severity`, default: `vim.diagnostic.severity.ERROR`)
|
diagnostic |vim.diagnostic.severity|
|
||||||
The severity of the diagnostic |vim.diagnostic.severity|
|
|
||||||
• {message} (`string`) The diagnostic text
|
• {message} (`string`) The diagnostic text
|
||||||
• {source}? (`string`) The source of the diagnostic
|
• {source}? (`string`) The source of the diagnostic
|
||||||
• {code}? (`string|integer`) The diagnostic code
|
• {code}? (`string|integer`) The diagnostic code
|
||||||
• {user_data}? (`any`) arbitrary data plugins can add
|
• {user_data}? (`any`) arbitrary data plugins can add
|
||||||
|
• {namespace}? (`integer`)
|
||||||
|
|
||||||
*vim.diagnostic.GetOpts*
|
*vim.diagnostic.GetOpts*
|
||||||
A table with the following keys:
|
A table with the following keys:
|
||||||
@@ -488,9 +450,6 @@ Lua module: vim.diagnostic *diagnostic-api*
|
|||||||
specified line number.
|
specified line number.
|
||||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||||
|diagnostic-severity|.
|
|diagnostic-severity|.
|
||||||
• {enabled}? (`boolean`, default: `nil`) Limit diagnostics to only
|
|
||||||
enabled or disabled. If nil, enablement is ignored. See
|
|
||||||
|vim.diagnostic.enable()|
|
|
||||||
|
|
||||||
*vim.diagnostic.JumpOpts*
|
*vim.diagnostic.JumpOpts*
|
||||||
Extends: |vim.diagnostic.GetOpts|
|
Extends: |vim.diagnostic.GetOpts|
|
||||||
@@ -516,9 +475,13 @@ Lua module: vim.diagnostic *diagnostic-api*
|
|||||||
file or not. Similar to 'wrapscan'.
|
file or not. Similar to 'wrapscan'.
|
||||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||||
|diagnostic-severity|.
|
|diagnostic-severity|.
|
||||||
• {on_jump}? (`fun(diagnostic:vim.Diagnostic?, bufnr:integer)`)
|
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default: `false`)
|
||||||
Optional callback invoked with the diagnostic that was
|
If `true`, call |vim.diagnostic.open_float()| after
|
||||||
jumped to.
|
moving. If a table, pass the table as the {opts}
|
||||||
|
parameter to |vim.diagnostic.open_float()|. Unless
|
||||||
|
overridden, the float will show diagnostics at the new
|
||||||
|
cursor position (as if "cursor" were passed to the
|
||||||
|
"scope" option).
|
||||||
• {winid}? (`integer`, default: `0`) Window ID
|
• {winid}? (`integer`, default: `0`) Window ID
|
||||||
|
|
||||||
*vim.diagnostic.NS*
|
*vim.diagnostic.NS*
|
||||||
@@ -572,8 +535,7 @@ Lua module: vim.diagnostic *diagnostic-api*
|
|||||||
Fields: ~
|
Fields: ~
|
||||||
• {bufnr}? (`integer`, default: current buffer) Buffer number
|
• {bufnr}? (`integer`, default: current buffer) Buffer number
|
||||||
to show diagnostics from.
|
to show diagnostics from.
|
||||||
• {namespace}? (`integer|integer[]`) Limit diagnostics to the given
|
• {namespace}? (`integer`) Limit diagnostics to the given namespace
|
||||||
namespace(s).
|
|
||||||
• {scope}? (`'line'|'buffer'|'cursor'|'c'|'l'|'b'`, default:
|
• {scope}? (`'line'|'buffer'|'cursor'|'c'|'l'|'b'`, default:
|
||||||
`line`) Show diagnostics from the whole buffer
|
`line`) Show diagnostics from the whole buffer
|
||||||
(`buffer"`, the current cursor line (`line`), or the
|
(`buffer"`, the current cursor line (`line`), or the
|
||||||
@@ -631,8 +593,8 @@ Lua module: vim.diagnostic *diagnostic-api*
|
|||||||
*vim.diagnostic.Opts.Jump*
|
*vim.diagnostic.Opts.Jump*
|
||||||
|
|
||||||
Fields: ~
|
Fields: ~
|
||||||
• {on_jump}? (`fun(diagnostic:vim.Diagnostic?, bufnr:integer)`)
|
• {float}? (`boolean|vim.diagnostic.Opts.Float`, default: false)
|
||||||
Default value of the {on_jump} parameter of
|
Default value of the {float} parameter of
|
||||||
|vim.diagnostic.jump()|.
|
|vim.diagnostic.jump()|.
|
||||||
• {wrap}? (`boolean`, default: true) Default value of the {wrap}
|
• {wrap}? (`boolean`, default: true) Default value of the {wrap}
|
||||||
parameter of |vim.diagnostic.jump()|.
|
parameter of |vim.diagnostic.jump()|.
|
||||||
@@ -692,12 +654,8 @@ Lua module: vim.diagnostic *diagnostic-api*
|
|||||||
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show
|
• {severity}? (`vim.diagnostic.SeverityFilter`) Only show
|
||||||
virtual text for diagnostics matching the given
|
virtual text for diagnostics matching the given
|
||||||
severity |diagnostic-severity|
|
severity |diagnostic-severity|
|
||||||
• {current_line}? (`boolean`) Show or hide diagnostics based on
|
• {current_line}? (`boolean`) Only show diagnostics for the
|
||||||
the current cursor line. If `true`, only
|
current line. (default `false`)
|
||||||
diagnostics on the current cursor line are
|
|
||||||
shown. If `false`, all diagnostics are shown
|
|
||||||
except on the current cursor line. If `nil`, all
|
|
||||||
diagnostics are shown. (default `nil`)
|
|
||||||
• {source}? (`boolean|"if_many"`) Include the diagnostic
|
• {source}? (`boolean|"if_many"`) Include the diagnostic
|
||||||
source in virtual text. Use `'if_many'` to only
|
source in virtual text. Use `'if_many'` to only
|
||||||
show sources if there is more than one
|
show sources if there is more than one
|
||||||
@@ -956,7 +914,7 @@ set({namespace}, {bufnr}, {diagnostics}, {opts}) *vim.diagnostic.set()*
|
|||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {namespace} (`integer`) The diagnostic namespace
|
• {namespace} (`integer`) The diagnostic namespace
|
||||||
• {bufnr} (`integer`) Buffer number
|
• {bufnr} (`integer`) Buffer number
|
||||||
• {diagnostics} (`vim.Diagnostic.Set[]`) See |vim.Diagnostic.Set|.
|
• {diagnostics} (`vim.Diagnostic[]`) See |vim.Diagnostic|.
|
||||||
• {opts} (`vim.diagnostic.Opts?`) Display options to pass to
|
• {opts} (`vim.diagnostic.Opts?`) Display options to pass to
|
||||||
|vim.diagnostic.show()|. See |vim.diagnostic.Opts|.
|
|vim.diagnostic.show()|. See |vim.diagnostic.Opts|.
|
||||||
|
|
||||||
@@ -965,8 +923,8 @@ setloclist({opts}) *vim.diagnostic.setloclist()*
|
|||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {opts} (`table?`) Configuration table with the following keys:
|
• {opts} (`table?`) Configuration table with the following keys:
|
||||||
• {namespace}? (`integer[]|integer`) Only add diagnostics from
|
• {namespace}? (`integer`) Only add diagnostics from the given
|
||||||
the given namespace(s).
|
namespace.
|
||||||
• {winnr}? (`integer`, default: `0`) Window number to set
|
• {winnr}? (`integer`, default: `0`) Window number to set
|
||||||
location list for.
|
location list for.
|
||||||
• {open}? (`boolean`, default: `true`) Open the location list
|
• {open}? (`boolean`, default: `true`) Open the location list
|
||||||
@@ -975,19 +933,14 @@ setloclist({opts}) *vim.diagnostic.setloclist()*
|
|||||||
"Diagnostics".
|
"Diagnostics".
|
||||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||||
|diagnostic-severity|.
|
|diagnostic-severity|.
|
||||||
• {format}? (`fun(diagnostic:vim.Diagnostic): string?`) A
|
|
||||||
function that takes a diagnostic as input and returns a
|
|
||||||
string or nil. If the return value is nil, the diagnostic is
|
|
||||||
not displayed in the location list. Else the output text is
|
|
||||||
used to display the diagnostic.
|
|
||||||
|
|
||||||
setqflist({opts}) *vim.diagnostic.setqflist()*
|
setqflist({opts}) *vim.diagnostic.setqflist()*
|
||||||
Add all diagnostics to the quickfix list.
|
Add all diagnostics to the quickfix list.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {opts} (`table?`) Configuration table with the following keys:
|
• {opts} (`table?`) Configuration table with the following keys:
|
||||||
• {namespace}? (`integer[]|integer`) Only add diagnostics from
|
• {namespace}? (`integer`) Only add diagnostics from the given
|
||||||
the given namespace(s).
|
namespace.
|
||||||
• {open}? (`boolean`, default: `true`) Open quickfix list
|
• {open}? (`boolean`, default: `true`) Open quickfix list
|
||||||
after setting.
|
after setting.
|
||||||
• {title}? (`string`) Title of quickfix list. Defaults to
|
• {title}? (`string`) Title of quickfix list. Defaults to
|
||||||
@@ -995,11 +948,6 @@ setqflist({opts}) *vim.diagnostic.setqflist()*
|
|||||||
title, it's updated. If not, a new quickfix list is created.
|
title, it's updated. If not, a new quickfix list is created.
|
||||||
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|
||||||
|diagnostic-severity|.
|
|diagnostic-severity|.
|
||||||
• {format}? (`fun(diagnostic:vim.Diagnostic): string?`) A
|
|
||||||
function that takes a diagnostic as input and returns a
|
|
||||||
string or nil. If the return value is nil, the diagnostic is
|
|
||||||
not displayed in the quickfix list. Else the output text is
|
|
||||||
used to display the diagnostic.
|
|
||||||
|
|
||||||
*vim.diagnostic.show()*
|
*vim.diagnostic.show()*
|
||||||
show({namespace}, {bufnr}, {diagnostics}, {opts})
|
show({namespace}, {bufnr}, {diagnostics}, {opts})
|
||||||
@@ -1019,23 +967,6 @@ show({namespace}, {bufnr}, {diagnostics}, {opts})
|
|||||||
• {opts} (`vim.diagnostic.Opts?`) Display options. See
|
• {opts} (`vim.diagnostic.Opts?`) Display options. See
|
||||||
|vim.diagnostic.Opts|.
|
|vim.diagnostic.Opts|.
|
||||||
|
|
||||||
status({bufnr}) *vim.diagnostic.status()*
|
|
||||||
Returns formatted string with diagnostics for the current buffer. The
|
|
||||||
severities with 0 diagnostics are left out. Example `E:2 W:3 I:4 H:5`
|
|
||||||
|
|
||||||
To customise appearance, set diagnostic signs text with >lua
|
|
||||||
vim.diagnostic.config({
|
|
||||||
signs = { text = { [vim.diagnostic.severity.ERROR] = 'e', ... } }
|
|
||||||
})
|
|
||||||
<
|
|
||||||
|
|
||||||
Parameters: ~
|
|
||||||
• {bufnr} (`integer?`) Buffer number to get diagnostics from. Defaults
|
|
||||||
to 0 for the current buffer
|
|
||||||
|
|
||||||
Return: ~
|
|
||||||
(`string`)
|
|
||||||
|
|
||||||
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
|
toqflist({diagnostics}) *vim.diagnostic.toqflist()*
|
||||||
Convert a list of diagnostics to a list of quickfix items that can be
|
Convert a list of diagnostics to a list of quickfix items that can be
|
||||||
passed to |setqflist()| or |setloclist()|.
|
passed to |setqflist()| or |setloclist()|.
|
||||||
|
@@ -214,28 +214,14 @@ The diffs are highlighted with these groups:
|
|||||||
|hl-DiffAdd| DiffAdd Added (inserted) lines. These lines exist in
|
|hl-DiffAdd| DiffAdd Added (inserted) lines. These lines exist in
|
||||||
this buffer but not in another.
|
this buffer but not in another.
|
||||||
|hl-DiffChange| DiffChange Changed lines.
|
|hl-DiffChange| DiffChange Changed lines.
|
||||||
|hl-DiffText| DiffText Changed text inside a Changed line. Exact
|
|hl-DiffText| DiffText Changed text inside a Changed line. Vim
|
||||||
behavior depends on the `inline:` setting in
|
finds the first character that is different,
|
||||||
'diffopt'.
|
and the last character that is different
|
||||||
With `inline:` set to "simple", Vim finds the
|
(searching from the end of the line). The
|
||||||
first character that is different, and the
|
text in between is highlighted. This means
|
||||||
last character that is different (searching
|
that parts in the middle that are still the
|
||||||
from the end of the line). The text in
|
same are highlighted anyway. The 'diffopt'
|
||||||
between is highlighted. This means that parts
|
flags "iwhite" and "icase" are used here.
|
||||||
in the middle that are still the same are
|
|
||||||
highlighted anyway. The 'diffopt' flags
|
|
||||||
"iwhite" and "icase" are used here.
|
|
||||||
With `inline:` set to "char" or "word", Vim
|
|
||||||
uses the internal diff library to perform a
|
|
||||||
detailed diff between the changed blocks and
|
|
||||||
highlight the exact difference between the
|
|
||||||
two. Will respect any 'diffopt' flag that
|
|
||||||
affects internal diff.
|
|
||||||
Not used when `inline:` is set to "none".
|
|
||||||
|hl-DiffTextAdd| DiffTextAdd Added text inside a Changed line. Similar to
|
|
||||||
DiffText, but used when there is no
|
|
||||||
corresponding text in other buffers. Not used
|
|
||||||
when `inline:` is set to "simple" or "none".
|
|
||||||
|hl-DiffDelete| DiffDelete Deleted lines. Also called filler lines,
|
|hl-DiffDelete| DiffDelete Deleted lines. Also called filler lines,
|
||||||
because they don't really exist in this
|
because they don't really exist in this
|
||||||
buffer.
|
buffer.
|
||||||
@@ -292,20 +278,18 @@ that the buffers will be equal within the specified range.
|
|||||||
|
|
||||||
|
|
||||||
When no [range] is given, the diff at the cursor position or just above it is
|
When no [range] is given, the diff at the cursor position or just above it is
|
||||||
affected. There can be deleted lines below the last line of the buffer. When
|
affected. When [range] is used, Vim tries to only put or get the specified
|
||||||
the cursor is on the last line in the buffer and there is no diff above this
|
lines. When there are deleted lines, this may not always be possible.
|
||||||
line, and no [range] is given, the diff below the cursor position will be used
|
|
||||||
instead.
|
|
||||||
|
|
||||||
When [range] is used, Vim tries to only put or get the specified lines. When
|
There can be deleted lines below the last line of the buffer. When the cursor
|
||||||
there are deleted lines, they will be used if they are between the lines
|
is on the last line in the buffer and there is no diff above this line, the
|
||||||
specified by [range].
|
":diffget" and "do" commands will obtain lines from the other buffer.
|
||||||
|
|
||||||
To be able to put or get those lines to/from another buffer in a [range] it's
|
To be able to get those lines from another buffer in a [range] it's allowed to
|
||||||
allowed to use 0 and the last line number plus one. This command gets all
|
use the last line number plus one. This command gets all diffs from the other
|
||||||
diffs from the other buffer: >
|
buffer: >
|
||||||
|
|
||||||
:0,$+1diffget
|
:1,$+1diffget
|
||||||
|
|
||||||
Note that deleted lines are displayed, but not counted as text lines. You
|
Note that deleted lines are displayed, but not counted as text lines. You
|
||||||
can't move the cursor into them. To fill the deleted lines with the lines
|
can't move the cursor into them. To fill the deleted lines with the lines
|
||||||
@@ -324,131 +308,9 @@ name or a part of a buffer name. Examples:
|
|||||||
diff mode (e.g., "file.c.v2")
|
diff mode (e.g., "file.c.v2")
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
5. Diff anchors *diff-anchors*
|
5. Diff options *diff-options*
|
||||||
|
|
||||||
Diff anchors allow you to control where the diff algorithm aligns and
|
Also see |'diffopt'| and the "diff" item of |'fillchars'|.
|
||||||
synchronize text across files. Each anchor matches each other in each file,
|
|
||||||
allowing you to control the output of a diff.
|
|
||||||
|
|
||||||
This is useful when a change involves complicated edits. For example, if a
|
|
||||||
function was moved to another location and further edited. By default, the
|
|
||||||
algorithm aims to create the smallest diff, which results in that entire
|
|
||||||
function being considered to be deleted and added on the other side, making it
|
|
||||||
hard to see what the actual edit on it was. You can use diff anchors to pin
|
|
||||||
that function so the diff algorithm will align based on it.
|
|
||||||
|
|
||||||
To use it, set anchors using 'diffanchors' which is a comma-separated list of
|
|
||||||
{address} in each file, and then add "anchor" to 'diffopt'. Internaly, Vim
|
|
||||||
splits each file up into sections split by the anchors. It performs the diff
|
|
||||||
on each pair of sections separately before merging the results back.
|
|
||||||
|
|
||||||
Setting 'diffanchors' will update the diff immediately. If an anchor is tied
|
|
||||||
to a mark, and you change what the mark is pointed to, you need to manually
|
|
||||||
call |:diffupdate| afterwards to get the updated diff results.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
Let's say we have the following files, side-by-side. We are interested in the
|
|
||||||
change that happened to the function `foo()`, which was both edited and moved.
|
|
||||||
|
|
||||||
File A: >
|
|
||||||
int foo() {
|
|
||||||
int n = 1;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int g = 1;
|
|
||||||
|
|
||||||
int bar(int a) {
|
|
||||||
a *= 2;
|
|
||||||
a += 3;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
<File B: >
|
|
||||||
int bar(int a) {
|
|
||||||
a *= 2;
|
|
||||||
a += 3;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
int foo() {
|
|
||||||
int n = 999;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
int g = 1;
|
|
||||||
<
|
|
||||||
A normal diff will usually align the diff result as such: >
|
|
||||||
|
|
||||||
int foo() { |----------------
|
|
||||||
int n = 1; |----------------
|
|
||||||
return n; |----------------
|
|
||||||
} |----------------
|
|
||||||
|----------------
|
|
||||||
int g = 1; |----------------
|
|
||||||
|----------------
|
|
||||||
int bar(int a) {|int bar(int a) {
|
|
||||||
a *= 2; | a *= 2;
|
|
||||||
a += 3; | a += 3;
|
|
||||||
return a; | return a;
|
|
||||||
} |}
|
|
||||||
----------------|
|
|
||||||
----------------|int foo() {
|
|
||||||
----------------| int n = 999;
|
|
||||||
----------------| return n;
|
|
||||||
----------------|}
|
|
||||||
----------------|
|
|
||||||
----------------|int g = 1;
|
|
||||||
<
|
|
||||||
What we want is to instead ask the diff to align on `foo()`: >
|
|
||||||
|
|
||||||
----------------|int bar(int a) {
|
|
||||||
----------------| a *= 2;
|
|
||||||
----------------| a += 3;
|
|
||||||
----------------| return a;
|
|
||||||
----------------|}
|
|
||||||
----------------|
|
|
||||||
int foo() { |int foo() {
|
|
||||||
int n = 1; | int n = 999;
|
|
||||||
return n; | return n;
|
|
||||||
} |}
|
|
||||||
|
|
|
||||||
int g = 1; |int g = 1;
|
|
||||||
|----------------
|
|
||||||
int bar(int a) {|----------------
|
|
||||||
a *= 2; |----------------
|
|
||||||
a += 3; |----------------
|
|
||||||
return a; |----------------
|
|
||||||
} |----------------
|
|
||||||
<
|
|
||||||
|
|
||||||
Below are some ways of setting diff anchors to get the above result. In each
|
|
||||||
example, 'diffopt' needs to have `anchor` set for this to take effect.
|
|
||||||
|
|
||||||
Marks: Set the |'a| mark on the `int foo()` lines in each file first before
|
|
||||||
setting the anchors: >
|
|
||||||
set diffanchors='a
|
|
||||||
|
|
||||||
Pattern: Specify the anchor using a |pattern| (see |:/|). Here, we make sure
|
|
||||||
to always start search from line 1 for consistency: >
|
|
||||||
set diffanchors=1/int\ foo(/
|
|
||||||
<
|
|
||||||
Selection: Use visual mode to select the entire `foo()` function body in each
|
|
||||||
file. Here, we use two anchors. This does a better job of making sure only
|
|
||||||
the function bodies are anchored against each other but not the lines after
|
|
||||||
it. Note the `'>+1` below. The "+1" is necessary as we want the split to
|
|
||||||
happen below the last line of the function, not above: >
|
|
||||||
set diffanchors='<,'>+1
|
|
||||||
<
|
|
||||||
Manually set two anchors using line numbers via buffer-local options: >
|
|
||||||
setlocal diffanchors=1,5
|
|
||||||
wincmd w
|
|
||||||
setlocal diffanchors=7,11
|
|
||||||
<
|
|
||||||
==============================================================================
|
|
||||||
6. Diff options *diff-options*
|
|
||||||
|
|
||||||
Also see 'diffopt' and the "diff" item of 'fillchars'.
|
|
||||||
|
|
||||||
*diff-slow* *diff_translations*
|
*diff-slow* *diff_translations*
|
||||||
For very long lines, the diff syntax highlighting might be slow, especially
|
For very long lines, the diff syntax highlighting might be slow, especially
|
||||||
|
@@ -1094,8 +1094,8 @@ the 1', 2' and 3' digraphs.
|
|||||||
⌕ TR 2315 8981 TELEPHONE RECORDER
|
⌕ TR 2315 8981 TELEPHONE RECORDER
|
||||||
⌠ Iu 2320 8992 TOP HALF INTEGRAL
|
⌠ Iu 2320 8992 TOP HALF INTEGRAL
|
||||||
⌡ Il 2321 8993 BOTTOM HALF INTEGRAL
|
⌡ Il 2321 8993 BOTTOM HALF INTEGRAL
|
||||||
⟨ <[ 27E8 10040 LEFT MATHEMATICAL ANGLE BRACKET
|
〈 </ 2329 9001 LEFT-POINTING ANGLE BRACKET
|
||||||
⟩ ]> 27E9 10041 RIGHT MATHEMATICAL ANGLE BRACKET
|
〉 /> 232A 9002 RIGHT-POINTING ANGLE BRACKET
|
||||||
␣ Vs 2423 9251 OPEN BOX
|
␣ Vs 2423 9251 OPEN BOX
|
||||||
⑀ 1h 2440 9280 OCR HOOK
|
⑀ 1h 2440 9280 OCR HOOK
|
||||||
⑁ 3h 2441 9281 OCR CHAIR
|
⑁ 3h 2441 9281 OCR CHAIR
|
||||||
|
@@ -630,7 +630,7 @@ list of the current window.
|
|||||||
buffer.
|
buffer.
|
||||||
Also see |++opt| and |+cmd|.
|
Also see |++opt| and |+cmd|.
|
||||||
|
|
||||||
:[count]arge[dit][!] [++opt] [+cmd] {name} ... *:arge* *:argedit*
|
:[count]arge[dit][!] [++opt] [+cmd] {name} .. *:arge* *:argedit*
|
||||||
Add {name}s to the argument list and edit it.
|
Add {name}s to the argument list and edit it.
|
||||||
There is no check for duplicates, it is possible to
|
There is no check for duplicates, it is possible to
|
||||||
add a file to the argument list twice |:argded|.
|
add a file to the argument list twice |:argded|.
|
||||||
@@ -645,7 +645,7 @@ list of the current window.
|
|||||||
edited. No check for duplicates is done.
|
edited. No check for duplicates is done.
|
||||||
Also see |++opt| and |+cmd|.
|
Also see |++opt| and |+cmd|.
|
||||||
|
|
||||||
:[count]arga[dd] {name} ... *:arga* *:argadd* *E479*
|
:[count]arga[dd] {name} .. *:arga* *:argadd* *E479*
|
||||||
:[count]arga[dd] *E1156*
|
:[count]arga[dd] *E1156*
|
||||||
Add the {name}s to the argument list. When {name} is
|
Add the {name}s to the argument list. When {name} is
|
||||||
omitted add the current buffer name to the argument
|
omitted add the current buffer name to the argument
|
||||||
@@ -676,7 +676,7 @@ list of the current window.
|
|||||||
If your current file is a duplicate, your current file
|
If your current file is a duplicate, your current file
|
||||||
will change to the original file index.
|
will change to the original file index.
|
||||||
|
|
||||||
:argd[elete] {pattern} ... *:argd* *:argdelete* *E480* *E610*
|
:argd[elete] {pattern} .. *:argd* *:argdelete* *E480* *E610*
|
||||||
Delete files from the argument list that match the
|
Delete files from the argument list that match the
|
||||||
{pattern}s. {pattern} is used like a file pattern,
|
{pattern}s. {pattern} is used like a file pattern,
|
||||||
see |file-pattern|. "%" can be used to delete the
|
see |file-pattern|. "%" can be used to delete the
|
||||||
@@ -960,9 +960,8 @@ Note: When the 'write' option is off, you are not able to write any file.
|
|||||||
executed like with ":!{cmd}", any '!' is replaced with
|
executed like with ":!{cmd}", any '!' is replaced with
|
||||||
the previous command |:!|.
|
the previous command |:!|.
|
||||||
|
|
||||||
The default [range] for the ":w" command is the whole buffer (1,$). The |'[|
|
The default [range] for the ":w" command is the whole buffer (1,$). If you
|
||||||
and |']| marks will be set to the [range] being used for the write command.
|
write the whole buffer, it is no longer considered changed. When you
|
||||||
If you write the whole buffer, it is no longer considered changed. When you
|
|
||||||
write it to a different file with ":w somefile" it depends on the "+" flag in
|
write it to a different file with ":w somefile" it depends on the "+" flag in
|
||||||
'cpoptions'. When included, the write command will reset the 'modified' flag,
|
'cpoptions'. When included, the write command will reset the 'modified' flag,
|
||||||
even though the buffer itself may still be different from its file.
|
even though the buffer itself may still be different from its file.
|
||||||
@@ -1242,10 +1241,10 @@ MULTIPLE WINDOWS AND BUFFERS *window-exit*
|
|||||||
*:confirm* *:conf*
|
*:confirm* *:conf*
|
||||||
:conf[irm] {command} Execute {command}, and use a dialog when an
|
:conf[irm] {command} Execute {command}, and use a dialog when an
|
||||||
operation has to be confirmed. Can be used on the
|
operation has to be confirmed. Can be used on the
|
||||||
|:edit|, |:restart|, |:q|, |:qa| and |:w| commands
|
|:edit|, |:q|, |:qa| and |:w| commands (the latter to
|
||||||
(the latter to override a read-only setting), and any
|
override a read-only setting), and any commands that
|
||||||
commands that can fail because of unsaved changes,
|
can fail because of unsaved changes, such as |:only|,
|
||||||
such as |:only|, |:buffer|, |:bdelete|, etc.
|
|:buffer|, |:bdelete|, etc.
|
||||||
|
|
||||||
Examples: >
|
Examples: >
|
||||||
:confirm w foo
|
:confirm w foo
|
||||||
@@ -1316,15 +1315,9 @@ b:browsefilter variable. You would most likely set b:browsefilter in a
|
|||||||
filetype plugin, so that the browse dialog would contain entries related to
|
filetype plugin, so that the browse dialog would contain entries related to
|
||||||
the type of file you are currently editing. Disadvantage: This makes it
|
the type of file you are currently editing. Disadvantage: This makes it
|
||||||
difficult to start editing a file of a different type. To overcome this, you
|
difficult to start editing a file of a different type. To overcome this, you
|
||||||
can add the following as the final filter on Windows: >
|
may want to add "All Files (*.*)\t*\n" as the final filter on Windows or "All
|
||||||
|
Files (*)\t*\n" on other platforms, so that the user can still access any
|
||||||
All Files\t(*.*)\t*\n
|
desired file.
|
||||||
<
|
|
||||||
Or the following on other platforms, so that the user can still access any
|
|
||||||
desired file: >
|
|
||||||
|
|
||||||
All Files\t(*)\t*\n
|
|
||||||
<
|
|
||||||
|
|
||||||
To avoid setting browsefilter when Vim does not actually support it, you can
|
To avoid setting browsefilter when Vim does not actually support it, you can
|
||||||
use has("browsefilter"): >
|
use has("browsefilter"): >
|
||||||
@@ -1356,7 +1349,7 @@ exist, the next-higher scope in the hierarchy applies.
|
|||||||
|
|
||||||
:cd[!] {path} Change the current directory to {path}.
|
:cd[!] {path} Change the current directory to {path}.
|
||||||
If {path} is relative, it is searched for in the
|
If {path} is relative, it is searched for in the
|
||||||
directories listed in 'cdpath'.
|
directories listed in |'cdpath'|.
|
||||||
Clear any window-local directory.
|
Clear any window-local directory.
|
||||||
Does not change the meaning of an already opened file,
|
Does not change the meaning of an already opened file,
|
||||||
because its full path name is remembered. Files from
|
because its full path name is remembered. Files from
|
||||||
|
@@ -187,19 +187,20 @@ Run |:checkhealth| in Nvim for automatic diagnosis.
|
|||||||
|
|
||||||
Other hints:
|
Other hints:
|
||||||
|
|
||||||
- Read |provider-python| to learn how to install `pynvim`.
|
- The python `neovim` module was renamed to `pynvim` (long ago).
|
||||||
- Be sure you have the latest version of the `pynvim` Python module: >bash
|
- If you're using pyenv or virtualenv for the `pynvim` module
|
||||||
|
|
||||||
uv tool install --upgrade pynvim
|
|
||||||
<
|
|
||||||
See |provider-python| for other installation options.
|
|
||||||
- If you're manually creating a Python virtual environment for the `pynvim` module
|
|
||||||
https://pypi.org/project/pynvim/, you must set `g:python3_host_prog` to
|
https://pypi.org/project/pynvim/, you must set `g:python3_host_prog` to
|
||||||
the virtualenv's interpreter path.
|
the virtualenv's interpreter path.
|
||||||
|
- Read |provider-python|.
|
||||||
|
- Be sure you have the latest version of the `pynvim` Python module: >bash
|
||||||
|
|
||||||
|
python -m pip install setuptools
|
||||||
|
python -m pip install --upgrade pynvim
|
||||||
|
python3 -m pip install --upgrade pynvim
|
||||||
|
<
|
||||||
- Try with `nvim -u NORC` to make sure your config (|init.vim|) isn't causing a
|
- Try with `nvim -u NORC` to make sure your config (|init.vim|) isn't causing a
|
||||||
problem. If you get `E117: Unknown function`, that means there's a runtime
|
problem. If you get `E117: Unknown function`, that means there's a runtime
|
||||||
issue: |faq-runtime|.
|
issue: |faq-runtime|.
|
||||||
- The python `neovim` module was renamed to `pynvim` (long ago).
|
|
||||||
|
|
||||||
|
|
||||||
:CHECKHEALTH REPORTS E5009: INVALID $VIMRUNTIME ~
|
:CHECKHEALTH REPORTS E5009: INVALID $VIMRUNTIME ~
|
||||||
@@ -449,7 +450,10 @@ grow and enhance it. Changing the rules of Lua gains nothing in this context.
|
|||||||
|
|
||||||
WILL NEOVIM TRANSLATE VIMSCRIPT TO LUA, INSTEAD OF EXECUTING VIMSCRIPT DIRECTLY? ~
|
WILL NEOVIM TRANSLATE VIMSCRIPT TO LUA, INSTEAD OF EXECUTING VIMSCRIPT DIRECTLY? ~
|
||||||
|
|
||||||
We have no plans for transpiling Vimscript. It was explored in https://github.com/tjdevries/vim9jit
|
- We are experimenting with vim9jit https://github.com/tjdevries/vim9jit to
|
||||||
|
transpile Vim9script (Vim9's Vimscript variant) to Lua and have used this to
|
||||||
|
port Vim9 plugins https://github.com/neovim/neovim/pull/21662 to Nvim Lua.
|
||||||
|
- We have no plans for transpiling legacy Vimscript.
|
||||||
|
|
||||||
|
|
||||||
ARE PLUGIN AUTHORS ENCOURAGED TO PORT THEIR PLUGINS FROM VIMSCRIPT TO LUA? DO YOU PLAN ON SUPPORTING VIMSCRIPT INDEFINITELY? (#1152) ~
|
ARE PLUGIN AUTHORS ENCOURAGED TO PORT THEIR PLUGINS FROM VIMSCRIPT TO LUA? DO YOU PLAN ON SUPPORTING VIMSCRIPT INDEFINITELY? (#1152) ~
|
||||||
@@ -464,8 +468,4 @@ emphatically a fork of Vim in order to leverage the work already spent on
|
|||||||
thousands of Vim plugins, while enabling new types of plugins and
|
thousands of Vim plugins, while enabling new types of plugins and
|
||||||
integrations.
|
integrations.
|
||||||
|
|
||||||
That being said, reimplementing legacy plugins in Lua in order to make use of
|
|
||||||
Nvim API and to integrate with Nvim-specific features such as treesitter can
|
|
||||||
be worthwhile.
|
|
||||||
|
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -156,8 +156,6 @@ variables can be used to overrule the filetype used for certain extensions:
|
|||||||
`*.inc` g:filetype_inc
|
`*.inc` g:filetype_inc
|
||||||
`*.lsl` g:filetype_lsl
|
`*.lsl` g:filetype_lsl
|
||||||
`*.m` g:filetype_m |ft-mathematica-syntax|
|
`*.m` g:filetype_m |ft-mathematica-syntax|
|
||||||
`*[mM]makefile,*.mk,*.mak,[mM]akefile*`
|
|
||||||
g:make_flavor |ft-make-syntax|
|
|
||||||
`*.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md`
|
`*.markdown,*.mdown,*.mkd,*.mkdn,*.mdwn,*.md`
|
||||||
g:filetype_md |ft-pandoc-syntax|
|
g:filetype_md |ft-pandoc-syntax|
|
||||||
`*.mod` g:filetype_mod
|
`*.mod` g:filetype_mod
|
||||||
@@ -264,7 +262,7 @@ D. If your filetype can only be detected by inspecting the contents of the
|
|||||||
item of the 'runtimepath' option. Example for Unix: >
|
item of the 'runtimepath' option. Example for Unix: >
|
||||||
:!mkdir -p ~/.config/nvim
|
:!mkdir -p ~/.config/nvim
|
||||||
<
|
<
|
||||||
2. Create a Vim script file for doing this. Example: >
|
2. Create a vim script file for doing this. Example: >
|
||||||
if did_filetype() " filetype already set..
|
if did_filetype() " filetype already set..
|
||||||
finish " ..don't do these checks
|
finish " ..don't do these checks
|
||||||
endif
|
endif
|
||||||
@@ -625,16 +623,6 @@ possibilities: >
|
|||||||
The `:Cycle` command is also mapped to the CTRL-A and CTRL-X keys.
|
The `:Cycle` command is also mapped to the CTRL-A and CTRL-X keys.
|
||||||
For details, see `git-rebase --help`.
|
For details, see `git-rebase --help`.
|
||||||
|
|
||||||
GLEAM *ft-gleam-plugin*
|
|
||||||
|
|
||||||
By default the following options are set for the recommended gleam style: >
|
|
||||||
|
|
||||||
setlocal expandtab shiftwidth=2 softtabstop=2
|
|
||||||
|
|
||||||
To disable this behavior, set the following variable in your vimrc: >
|
|
||||||
|
|
||||||
let g:gleam_recommended_style = 0
|
|
||||||
|
|
||||||
GO *ft-go-plugin*
|
GO *ft-go-plugin*
|
||||||
|
|
||||||
By default the following options are set, based on Golang official docs: >
|
By default the following options are set, based on Golang official docs: >
|
||||||
@@ -661,32 +649,6 @@ HARE *ft-hare*
|
|||||||
Since the text for this plugin is rather long it has been put in a separate
|
Since the text for this plugin is rather long it has been put in a separate
|
||||||
file: |ft_hare.txt|.
|
file: |ft_hare.txt|.
|
||||||
|
|
||||||
HTML *ft-html-plugin*
|
|
||||||
|
|
||||||
Tag folding poses a few difficulties. Many elements, e.g. `blockquote`, are
|
|
||||||
always delimited by start and end tags; end tags for some elements, e.g. `p`,
|
|
||||||
can be omitted in certain contexts; void elements, e.g. `hr`, have no end tag.
|
|
||||||
Although the rules for supporting omissible end tags are ad-hoc and involved
|
|
||||||
[0], they apply to elements in scope. Assuming syntactical wellformedness, an
|
|
||||||
end tag can be associated with its nearest matching start tag discoverable in
|
|
||||||
scope [1] and towards the beginning of a file, whereas all unbalanced tags and
|
|
||||||
inlined tags can be disregarded. Having syntax highlighting in effect, tag
|
|
||||||
folding using the |fold-expr| method can be enabled with: >
|
|
||||||
let g:html_expr_folding = 1
|
|
||||||
<
|
|
||||||
By default, tag folding will be redone from scratch after each occurrence of
|
|
||||||
a |TextChanged| or an |InsertLeave| event. Such frequency may not be desired,
|
|
||||||
especially for large files, and this recomputation can be disabled with: >
|
|
||||||
let g:html_expr_folding_without_recomputation = 1
|
|
||||||
doautocmd FileType
|
|
||||||
<
|
|
||||||
To force another recomputation, do: >
|
|
||||||
unlet! b:foldsmap
|
|
||||||
normal zx
|
|
||||||
<
|
|
||||||
[0] https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
|
|
||||||
[1] https://en.wikipedia.org/wiki/Dangling_else
|
|
||||||
|
|
||||||
IDRIS2 *ft-idris2-plugin*
|
IDRIS2 *ft-idris2-plugin*
|
||||||
|
|
||||||
By default the following options are set: >
|
By default the following options are set: >
|
||||||
@@ -823,8 +785,8 @@ Variables:
|
|||||||
For example in C one usually wants section 3 or 2: >
|
For example in C one usually wants section 3 or 2: >
|
||||||
:let b:man_default_sections = '3,2'
|
:let b:man_default_sections = '3,2'
|
||||||
*g:man_hardwrap* Hard-wrap to $MANWIDTH or window width if $MANWIDTH is
|
*g:man_hardwrap* Hard-wrap to $MANWIDTH or window width if $MANWIDTH is
|
||||||
empty or larger than the window width. Enabled by
|
empty. Enabled by default. Set |FALSE| to enable soft
|
||||||
default. Set |FALSE| to enable soft wrapping.
|
wrapping.
|
||||||
|
|
||||||
To use Nvim as a manpager: >bash
|
To use Nvim as a manpager: >bash
|
||||||
export MANPAGER='nvim +Man!'
|
export MANPAGER='nvim +Man!'
|
||||||
@@ -1155,13 +1117,6 @@ functions with [[ and ]]. Move around comments with ]" and [".
|
|||||||
The mappings can be disabled with: >
|
The mappings can be disabled with: >
|
||||||
let g:no_vim_maps = 1
|
let g:no_vim_maps = 1
|
||||||
|
|
||||||
YAML *ft-yaml-plugin*
|
|
||||||
By default, the YAML filetype plugin enables the following options: >
|
|
||||||
setlocal shiftwidth=2 softtabstop=2
|
|
||||||
|
|
||||||
To disable this, set the following variable: >
|
|
||||||
let g:yaml_recommended_style = 0
|
|
||||||
|
|
||||||
|
|
||||||
ZIG *ft-zig-plugin*
|
ZIG *ft-zig-plugin*
|
||||||
|
|
||||||
|
@@ -632,17 +632,14 @@ what you type!
|
|||||||
When using an operator, a closed fold is included as a whole. Thus "dl"
|
When using an operator, a closed fold is included as a whole. Thus "dl"
|
||||||
deletes the whole closed fold under the cursor.
|
deletes the whole closed fold under the cursor.
|
||||||
|
|
||||||
For Ex commands that operate on buffer lines, the range is adjusted to always
|
For Ex commands that work on buffer lines the range is adjusted to always
|
||||||
start at the first line of a closed fold and end at the last line of a closed
|
start at the first line of a closed fold and end at the last line of a closed
|
||||||
fold. Thus, this command: >
|
fold. Thus this command: >
|
||||||
:s/foo/bar/g
|
:s/foo/bar/g
|
||||||
when used with the cursor on a closed fold, will replace "foo" with "bar" in
|
when used with the cursor on a closed fold, will replace "foo" with "bar" in
|
||||||
all lines of the fold.
|
all lines of the fold.
|
||||||
This does not happen for |:folddoopen| and |:folddoclosed|.
|
This does not happen for |:folddoopen| and |:folddoclosed|.
|
||||||
|
|
||||||
Note that for some Ex commands like |:source| the range is only adjusted when
|
|
||||||
using a two line specifiers [range].
|
|
||||||
|
|
||||||
When editing a buffer that has been edited before, the last used folding
|
When editing a buffer that has been edited before, the last used folding
|
||||||
settings are used again. For manual folding the defined folds are restored.
|
settings are used again. For manual folding the defined folds are restored.
|
||||||
For all folding methods the manually opened and closed folds are restored.
|
For all folding methods the manually opened and closed folds are restored.
|
||||||
@@ -650,4 +647,5 @@ If this buffer has been edited in this window, the values from back then are
|
|||||||
used. Otherwise the values from the window where the buffer was edited last
|
used. Otherwise the values from the window where the buffer was edited last
|
||||||
are used.
|
are used.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -76,8 +76,8 @@ The Ada plug-in provides support for:
|
|||||||
- user completion (|i_CTRL-X_CTRL-U|)
|
- user completion (|i_CTRL-X_CTRL-U|)
|
||||||
- tag searches (|tagsrch.txt|)
|
- tag searches (|tagsrch.txt|)
|
||||||
- Quick Fix (|quickfix.txt|)
|
- Quick Fix (|quickfix.txt|)
|
||||||
- backspace handling ('backspace')
|
- backspace handling (|'backspace'|)
|
||||||
- comment handling ('comments', 'commentstring')
|
- comment handling (|'comments'|, |'commentstring'|)
|
||||||
|
|
||||||
The plug-in only activates the features of the Ada mode whenever an Ada
|
The plug-in only activates the features of the Ada mode whenever an Ada
|
||||||
file is opened and adds Ada related entries to the main and pop-up menu.
|
file is opened and adds Ada related entries to the main and pop-up menu.
|
||||||
@@ -197,7 +197,7 @@ g:gnat.Project_File string
|
|||||||
|
|
||||||
*g:gnat.Make_Command*
|
*g:gnat.Make_Command*
|
||||||
g:gnat.Make_Command string
|
g:gnat.Make_Command string
|
||||||
External command used for |g:gnat.Make()| ('makeprg').
|
External command used for |g:gnat.Make()| (|'makeprg'|).
|
||||||
|
|
||||||
*g:gnat.Pretty_Program*
|
*g:gnat.Pretty_Program*
|
||||||
g:gnat.Pretty_Program string
|
g:gnat.Pretty_Program string
|
||||||
@@ -213,7 +213,7 @@ g:gnat.Tags_Command string
|
|||||||
|
|
||||||
*g:gnat.Error_Format*
|
*g:gnat.Error_Format*
|
||||||
g:gnat.Error_Format string
|
g:gnat.Error_Format string
|
||||||
Error format ('errorformat')
|
Error format (|'errorformat'|)
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
4.2 Dec Ada ~
|
4.2 Dec Ada ~
|
||||||
@@ -243,11 +243,11 @@ g:decada.Unit_Name() function
|
|||||||
|
|
||||||
*g:decada.Make_Command*
|
*g:decada.Make_Command*
|
||||||
g:decada.Make_Command string
|
g:decada.Make_Command string
|
||||||
External command used for |g:decada.Make()| ('makeprg').
|
External command used for |g:decada.Make()| (|'makeprg'|).
|
||||||
|
|
||||||
*g:decada.Error_Format*
|
*g:decada.Error_Format*
|
||||||
g:decada.Error_Format string
|
g:decada.Error_Format string
|
||||||
Error format ('errorformat').
|
Error format (|'errorformat'|).
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
5. References ~
|
5. References ~
|
||||||
@@ -507,4 +507,6 @@ taglist.vim
|
|||||||
The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim
|
The GNU Ada Project distribution (http://gnuada.sourceforge.net) of Vim
|
||||||
contains all of the above.
|
contains all of the above.
|
||||||
|
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
==============================================================================
|
||||||
|
vim: textwidth=78 nowrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab
|
||||||
|
vim: filetype=help
|
||||||
|
@@ -73,4 +73,5 @@ The maximum search depth can be set to any integer, but using values higher
|
|||||||
than 2 is not recommended, and will likely provide no tangible benefit in most
|
than 2 is not recommended, and will likely provide no tangible benefit in most
|
||||||
situations.
|
situations.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -60,4 +60,5 @@ Many other distributions are available for Windows like
|
|||||||
https://chocolatey.org/packages/less/. Make sure `less` is in a directory
|
https://chocolatey.org/packages/less/. Make sure `less` is in a directory
|
||||||
listed in the `PATH` environment variable, which chocolatey above does.
|
listed in the `PATH` environment variable, which chocolatey above does.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
vim:ft=help:
|
vim:ft=help:
|
||||||
|
@@ -160,18 +160,7 @@ g:rustfmt_emit_files ~
|
|||||||
provided) instead of '--write-mode=overwrite'. >vim
|
provided) instead of '--write-mode=overwrite'. >vim
|
||||||
let g:rustfmt_emit_files = 0
|
let g:rustfmt_emit_files = 0
|
||||||
<
|
<
|
||||||
*g:rustfmt_detect_version*
|
|
||||||
g:rustfmt_detect_version ~
|
|
||||||
When set to 1, will try to parse the version output from "rustfmt".
|
|
||||||
Disabled by default for performance reasons >vim
|
|
||||||
let g:rustfmt_detect_version = 1
|
|
||||||
<
|
|
||||||
*g:rustfmt_find_toml*
|
|
||||||
g:rustfmt_emit_files ~
|
|
||||||
When set to 1, will try to find "rustfmt.toml" file by searching from
|
|
||||||
current path upwards. Disabled by default for performance reasons >vim
|
|
||||||
let g:rustfmt_find_toml = 1
|
|
||||||
<
|
|
||||||
*g:rust_playpen_url*
|
*g:rust_playpen_url*
|
||||||
g:rust_playpen_url ~
|
g:rust_playpen_url ~
|
||||||
Set this option to override the url for the playpen to use: >vim
|
Set this option to override the url for the playpen to use: >vim
|
||||||
@@ -486,4 +475,4 @@ MAPPINGS *rust-mappings*
|
|||||||
This plugin defines mappings for |[[| and |]]| to support hanging indents.
|
This plugin defines mappings for |[[| and |]]| to support hanging indents.
|
||||||
|
|
||||||
|
|
||||||
vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
|
vim:tw=78:sw=4:noet:ts=8:ft=help:norl:
|
||||||
|
@@ -172,7 +172,7 @@ with comments: >
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
1.4 Macros *sql-macros*
|
1.4 Macros *sql-macros*
|
||||||
|
|
||||||
Vim's feature to find macro definitions, 'define', is supported using this
|
Vim's feature to find macro definitions, |'define'|, is supported using this
|
||||||
regular expression: >
|
regular expression: >
|
||||||
\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>
|
\c\<\(VARIABLE\|DECLARE\|IN\|OUT\|INOUT\)\>
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ key to complete the optional parameter.
|
|||||||
After typing the function name and a space, you can use the completion to
|
After typing the function name and a space, you can use the completion to
|
||||||
supply a parameter. The function takes the name of the Vim script you want to
|
supply a parameter. The function takes the name of the Vim script you want to
|
||||||
source. Using the |cmdline-completion| feature, the SQLSetType function will
|
source. Using the |cmdline-completion| feature, the SQLSetType function will
|
||||||
search the 'runtimepath' for all Vim scripts with a name containing "sql".
|
search the |'runtimepath'| for all Vim scripts with a name containing "sql".
|
||||||
This takes the guess work out of the spelling of the names. The following are
|
This takes the guess work out of the spelling of the names. The following are
|
||||||
examples: >
|
examples: >
|
||||||
:SQLSetType
|
:SQLSetType
|
||||||
@@ -412,7 +412,7 @@ Here are some examples of the entries which are pulled from the syntax files: >
|
|||||||
|
|
||||||
Dynamic mode populates the popups with data directly from a database. In
|
Dynamic mode populates the popups with data directly from a database. In
|
||||||
order for the dynamic feature to be enabled you must have the dbext.vim
|
order for the dynamic feature to be enabled you must have the dbext.vim
|
||||||
plugin installed, (https://www.vim.org/scripts/script.php?script_id=356).
|
plugin installed, (https://vim.sourceforge.net/script.php?script_id=356).
|
||||||
|
|
||||||
Dynamic mode is used by several features of the SQL completion plugin.
|
Dynamic mode is used by several features of the SQL completion plugin.
|
||||||
After installing the dbext plugin see the dbext-tutorial for additional
|
After installing the dbext plugin see the dbext-tutorial for additional
|
||||||
@@ -496,7 +496,7 @@ depending on the syntax file you are using. The SQL Anywhere syntax file
|
|||||||
Dynamic features ~
|
Dynamic features ~
|
||||||
|
|
||||||
To take advantage of the dynamic features you must first install the
|
To take advantage of the dynamic features you must first install the
|
||||||
dbext.vim plugin (https://www.vim.org/scripts/script.php?script_id=356). It
|
dbext.vim plugin (https://vim.sourceforge.net/script.php?script_id=356). It
|
||||||
also comes with a tutorial. From the SQL completion plugin's perspective,
|
also comes with a tutorial. From the SQL completion plugin's perspective,
|
||||||
the main feature dbext provides is a connection to a database. dbext
|
the main feature dbext provides is a connection to a database. dbext
|
||||||
connection profiles are the most efficient mechanism to define connection
|
connection profiles are the most efficient mechanism to define connection
|
||||||
@@ -760,7 +760,7 @@ Step 1 ~
|
|||||||
Begins by editing a Perl file. Vim automatically sets the filetype to
|
Begins by editing a Perl file. Vim automatically sets the filetype to
|
||||||
"perl". By default, Vim runs the appropriate filetype file
|
"perl". By default, Vim runs the appropriate filetype file
|
||||||
ftplugin/perl.vim. If you are using the syntax completion plugin by following
|
ftplugin/perl.vim. If you are using the syntax completion plugin by following
|
||||||
the directions at |ft-syntax-omni| then the 'omnifunc' option has been set to
|
the directions at |ft-syntax-omni| then the |'omnifunc'| option has been set to
|
||||||
"syntax#Complete". Pressing <C-X><C-O> will display the omni popup containing
|
"syntax#Complete". Pressing <C-X><C-O> will display the omni popup containing
|
||||||
the syntax items for Perl.
|
the syntax items for Perl.
|
||||||
|
|
||||||
@@ -772,7 +772,7 @@ maps for SQL completion, see |sql-completion-maps|. Now these maps have
|
|||||||
been created and the SQL completion plugin has been initialized. All SQL
|
been created and the SQL completion plugin has been initialized. All SQL
|
||||||
syntax items have been cached in preparation. The SQL filetype script detects
|
syntax items have been cached in preparation. The SQL filetype script detects
|
||||||
we are attempting to use two different completion plugins. Since the SQL maps
|
we are attempting to use two different completion plugins. Since the SQL maps
|
||||||
begin with <C-C>, the maps will toggle the 'omnifunc' when in use. So you
|
begin with <C-C>, the maps will toggle the |'omnifunc'| when in use. So you
|
||||||
can use <C-X><C-O> to continue using the completion for Perl (using the syntax
|
can use <C-X><C-O> to continue using the completion for Perl (using the syntax
|
||||||
completion plugin) and <C-C> to use the SQL completion features.
|
completion plugin) and <C-C> to use the SQL completion features.
|
||||||
|
|
||||||
|
@@ -17,8 +17,6 @@ TUI and GUI (assuming the UI supports the given feature). See |TUI| for notes
|
|||||||
specific to the terminal UI. Help tags with the "gui-" prefix refer to UI
|
specific to the terminal UI. Help tags with the "gui-" prefix refer to UI
|
||||||
features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
|
features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
|
||||||
|
|
||||||
Type |gO| to see the table of contents.
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Third-party GUIs *third-party-guis* *vscode*
|
Third-party GUIs *third-party-guis* *vscode*
|
||||||
|
|
||||||
@@ -36,6 +34,8 @@ a Nvim GUI.
|
|||||||
- VimR (macOS) https://github.com/qvacua/vimr
|
- VimR (macOS) https://github.com/qvacua/vimr
|
||||||
- Others https://github.com/neovim/neovim/wiki/Related-projects#gui
|
- Others https://github.com/neovim/neovim/wiki/Related-projects#gui
|
||||||
|
|
||||||
|
Type |gO| to see the table of contents.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Starting the GUI *gui-config* *gui-start*
|
Starting the GUI *gui-config* *gui-start*
|
||||||
|
|
||||||
@@ -64,50 +64,7 @@ Stop or detach the current UI
|
|||||||
the channel to be closed, it may be (incorrectly) reported as
|
the channel to be closed, it may be (incorrectly) reported as
|
||||||
an error.
|
an error.
|
||||||
|
|
||||||
Note: Not supported on Windows yet.
|
Note: Not supported on Windows, currently.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Restart Nvim
|
|
||||||
|
|
||||||
*:restart*
|
|
||||||
:restart [+cmd] [command]
|
|
||||||
Restarts Nvim.
|
|
||||||
|
|
||||||
1. Stops Nvim using `:qall!` (or |+cmd|, if given).
|
|
||||||
2. Starts a new Nvim server using the same |v:argv|,
|
|
||||||
optionally running [command] at startup. |-c|
|
|
||||||
3. Attaches the current UI to the new Nvim server. Other UIs
|
|
||||||
(if any) will not reattach on restart (this may change in
|
|
||||||
the future).
|
|
||||||
|
|
||||||
Use with `:confirm` to prompt if changes have been made.
|
|
||||||
|
|
||||||
Example: stop with `:qall!`, then restart: >
|
|
||||||
:restart +qall!
|
|
||||||
< Example: restart and restore the current session: >
|
|
||||||
:mksession! Session.vim | restart source Session.vim
|
|
||||||
< Example: restart and update plugins: >
|
|
||||||
:restart +qall! lua vim.pack.update()
|
|
||||||
<
|
|
||||||
Note: Only works if the UI and server are on the same system.
|
|
||||||
Note: If the UI hasn't implemented the "restart" UI event,
|
|
||||||
this command is equivalent to `:qall!`.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Connect UI to a different server
|
|
||||||
|
|
||||||
*:connect*
|
|
||||||
|
|
||||||
:connect {address}
|
|
||||||
Detaches the UI from the server it is currently attached to
|
|
||||||
and attaches it to the server at {address} instead.
|
|
||||||
|
|
||||||
Note: If the current UI hasn't implemented the "connect" UI
|
|
||||||
event, this command is equivalent to |:detach|.
|
|
||||||
|
|
||||||
:connect! {address}
|
|
||||||
Same as |:connect| but it also stops the detached server if
|
|
||||||
no other UI is currently attached to it.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
GUI commands
|
GUI commands
|
||||||
|
@@ -112,6 +112,7 @@ API (EXTENSIBILITY/SCRIPTING/PLUGINS)
|
|||||||
|channel| Nvim asynchronous IO
|
|channel| Nvim asynchronous IO
|
||||||
|vimscript| Vimscript reference
|
|vimscript| Vimscript reference
|
||||||
|vimscript-functions| Vimscript functions
|
|vimscript-functions| Vimscript functions
|
||||||
|
|testing.txt| Vimscript testing functions
|
||||||
|remote-plugin| Nvim remote plugins
|
|remote-plugin| Nvim remote plugins
|
||||||
|health| Health checking
|
|health| Health checking
|
||||||
|
|
||||||
|
@@ -337,7 +337,7 @@ in such a modeline, that can have undesired consequences.
|
|||||||
|
|
||||||
TAGS
|
TAGS
|
||||||
|
|
||||||
To define a help tag, place the name between asterisks ("*tag-name*"). The
|
To define a help tag, place the name between asterisks (*tag-name*). The
|
||||||
tag-name should be different from all the Vim help tag names and ideally
|
tag-name should be different from all the Vim help tag names and ideally
|
||||||
should begin with the name of the Vim plugin. The tag name is usually right
|
should begin with the name of the Vim plugin. The tag name is usually right
|
||||||
aligned on a line.
|
aligned on a line.
|
||||||
@@ -373,17 +373,11 @@ To quote a block of ex-commands verbatim, place a greater than (>) character
|
|||||||
at the end of the line before the block and a less than (<) character as the
|
at the end of the line before the block and a less than (<) character as the
|
||||||
first non-blank on a line following the block. Any line starting in column 1
|
first non-blank on a line following the block. Any line starting in column 1
|
||||||
also implicitly stops the block of ex-commands before it. E.g. >
|
also implicitly stops the block of ex-commands before it. E.g. >
|
||||||
function Example_Func()
|
function Example_Func()
|
||||||
echo "Example"
|
echo "Example"
|
||||||
endfunction
|
endfunction
|
||||||
<
|
<
|
||||||
To enable syntax highlighting for a block of code, place a language name
|
|
||||||
annotation (e.g. "vim") after a greater than (>) character. E.g. >vim
|
|
||||||
function Example_Func()
|
|
||||||
echo "Example"
|
|
||||||
endfunction
|
|
||||||
<
|
|
||||||
*help-notation*
|
|
||||||
The following are highlighted differently in a Vim help file:
|
The following are highlighted differently in a Vim help file:
|
||||||
- a special key name expressed either in <> notation as in <PageDown>, or
|
- a special key name expressed either in <> notation as in <PageDown>, or
|
||||||
as a Ctrl character as in CTRL-X
|
as a Ctrl character as in CTRL-X
|
||||||
@@ -397,10 +391,4 @@ highlighting. So do these:
|
|||||||
You can find the details in $VIMRUNTIME/syntax/help.vim
|
You can find the details in $VIMRUNTIME/syntax/help.vim
|
||||||
|
|
||||||
|
|
||||||
FILETYPE COMPLETION *ft-help-omni*
|
|
||||||
|
|
||||||
To get completion for help tags when writing a tag reference, you can use the
|
|
||||||
|i_CTRL-X_CTRL-O| command.
|
|
||||||
|
|
||||||
|
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -268,4 +268,5 @@ These are also available via the "main" package:
|
|||||||
$main::curwin The current Window object.
|
$main::curwin The current Window object.
|
||||||
$main::curbuf The current Buffer object.
|
$main::curbuf The current Buffer object.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -645,6 +645,6 @@ To check if `pyx*` functions and commands are available: >vim
|
|||||||
if has('pythonx')
|
if has('pythonx')
|
||||||
echo 'pyx* commands are available. (Python ' .. &pyx .. ')'
|
echo 'pyx* commands are available. (Python ' .. &pyx .. ')'
|
||||||
endif
|
endif
|
||||||
<
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -189,4 +189,5 @@ evaluate Ruby expressions and pass their values to Vim script.
|
|||||||
The Ruby value "true", "false" and "nil" are converted to v:true, v:false and
|
The Ruby value "true", "false" and "nil" are converted to v:true, v:false and
|
||||||
v:null, respectively.
|
v:null, respectively.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
@@ -146,7 +146,6 @@ commands in CTRL-X submode *i_CTRL-X_index*
|
|||||||
|i_CTRL-X_CTRL-N| CTRL-X CTRL-N next completion
|
|i_CTRL-X_CTRL-N| CTRL-X CTRL-N next completion
|
||||||
|i_CTRL-X_CTRL-O| CTRL-X CTRL-O omni completion
|
|i_CTRL-X_CTRL-O| CTRL-X CTRL-O omni completion
|
||||||
|i_CTRL-X_CTRL-P| CTRL-X CTRL-P previous completion
|
|i_CTRL-X_CTRL-P| CTRL-X CTRL-P previous completion
|
||||||
|i_CTRL-X_CTRL-R| CTRL-X CTRL-R complete contents from registers
|
|
||||||
|i_CTRL-X_CTRL-S| CTRL-X CTRL-S spelling suggestions
|
|i_CTRL-X_CTRL-S| CTRL-X CTRL-S spelling suggestions
|
||||||
|i_CTRL-X_CTRL-T| CTRL-X CTRL-T complete identifiers from thesaurus
|
|i_CTRL-X_CTRL-T| CTRL-X CTRL-T complete identifiers from thesaurus
|
||||||
|i_CTRL-X_CTRL-Y| CTRL-X CTRL-Y scroll down
|
|i_CTRL-X_CTRL-Y| CTRL-X CTRL-Y scroll down
|
||||||
@@ -516,7 +515,7 @@ tag command action in op-pending and Visual mode ~
|
|||||||
tag command action in Normal mode ~
|
tag command action in Normal mode ~
|
||||||
------------------------------------------------------------------------------ ~
|
------------------------------------------------------------------------------ ~
|
||||||
|CTRL-W_CTRL-B| CTRL-W CTRL-B same as "CTRL-W b"
|
|CTRL-W_CTRL-B| CTRL-W CTRL-B same as "CTRL-W b"
|
||||||
|CTRL-W_CTRL-C| CTRL-W CTRL-C no-op
|
|CTRL-W_CTRL-C| CTRL-W CTRL-C same as "CTRL-W c"
|
||||||
|CTRL-W_CTRL-D| CTRL-W CTRL-D same as "CTRL-W d"
|
|CTRL-W_CTRL-D| CTRL-W CTRL-D same as "CTRL-W d"
|
||||||
|CTRL-W_CTRL-F| CTRL-W CTRL-F same as "CTRL-W f"
|
|CTRL-W_CTRL-F| CTRL-W CTRL-F same as "CTRL-W f"
|
||||||
CTRL-W CTRL-G same as "CTRL-W g .."
|
CTRL-W CTRL-G same as "CTRL-W g .."
|
||||||
@@ -1017,7 +1016,7 @@ tag command action in Command-line editing mode ~
|
|||||||
|c_CTRL-D| CTRL-D list completions that match the pattern in
|
|c_CTRL-D| CTRL-D list completions that match the pattern in
|
||||||
front of the cursor
|
front of the cursor
|
||||||
|c_CTRL-E| CTRL-E cursor to end of command-line
|
|c_CTRL-E| CTRL-E cursor to end of command-line
|
||||||
'cedit' CTRL-F default value for 'cedit': opens the
|
|'cedit'| CTRL-F default value for 'cedit': opens the
|
||||||
command-line window; otherwise not used
|
command-line window; otherwise not used
|
||||||
|c_CTRL-G| CTRL-G next match when 'incsearch' is active
|
|c_CTRL-G| CTRL-G next match when 'incsearch' is active
|
||||||
|c_<BS>| <BS> delete the character in front of the cursor
|
|c_<BS>| <BS> delete the character in front of the cursor
|
||||||
@@ -1266,7 +1265,6 @@ tag command action ~
|
|||||||
|:delcommand| :delc[ommand] delete user-defined command
|
|:delcommand| :delc[ommand] delete user-defined command
|
||||||
|:delfunction| :delf[unction] delete a user function
|
|:delfunction| :delf[unction] delete a user function
|
||||||
|:delmarks| :delm[arks] delete marks
|
|:delmarks| :delm[arks] delete marks
|
||||||
|:detach| :detach detach the current UI
|
|
||||||
|:diffupdate| :dif[fupdate] update 'diff' buffers
|
|:diffupdate| :dif[fupdate] update 'diff' buffers
|
||||||
|:diffget| :diffg[et] remove differences in current buffer
|
|:diffget| :diffg[et] remove differences in current buffer
|
||||||
|:diffoff| :diffo[ff] switch off diff mode
|
|:diffoff| :diffo[ff] switch off diff mode
|
||||||
@@ -1350,8 +1348,6 @@ tag command action ~
|
|||||||
|:inoreabbrev| :inorea[bbrev] like ":noreabbrev" but for Insert mode
|
|:inoreabbrev| :inorea[bbrev] like ":noreabbrev" but for Insert mode
|
||||||
|:inoremenu| :inoreme[nu] like ":noremenu" but for Insert mode
|
|:inoremenu| :inoreme[nu] like ":noremenu" but for Insert mode
|
||||||
|:intro| :int[ro] print the introductory message
|
|:intro| :int[ro] print the introductory message
|
||||||
|:iput| :ip[ut] like |:put|, but adjust the indent to the
|
|
||||||
current line
|
|
||||||
|:isearch| :is[earch] list one line where identifier matches
|
|:isearch| :is[earch] list one line where identifier matches
|
||||||
|:isplit| :isp[lit] split window and jump to definition of
|
|:isplit| :isp[lit] split window and jump to definition of
|
||||||
identifier
|
identifier
|
||||||
@@ -1473,6 +1469,7 @@ tag command action ~
|
|||||||
|:options| :opt[ions] open the options-window
|
|:options| :opt[ions] open the options-window
|
||||||
|:ounmap| :ou[nmap] like ":unmap" but for Operator-pending mode
|
|:ounmap| :ou[nmap] like ":unmap" but for Operator-pending mode
|
||||||
|:ounmenu| :ounme[nu] remove menu for Operator-pending mode
|
|:ounmenu| :ounme[nu] remove menu for Operator-pending mode
|
||||||
|
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|
||||||
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|
||||||
|:packloadall| :packl[oadall] load all packages under 'packpath'
|
|:packloadall| :packl[oadall] load all packages under 'packpath'
|
||||||
|:pbuffer| :pb[uffer] edit buffer in the preview window
|
|:pbuffer| :pb[uffer] edit buffer in the preview window
|
||||||
@@ -1525,7 +1522,6 @@ tag command action ~
|
|||||||
|:redrawtabline| :redrawt[abline] force a redraw of the tabline
|
|:redrawtabline| :redrawt[abline] force a redraw of the tabline
|
||||||
|:registers| :reg[isters] display the contents of registers
|
|:registers| :reg[isters] display the contents of registers
|
||||||
|:resize| :res[ize] change current window height
|
|:resize| :res[ize] change current window height
|
||||||
|:restart| :restart restart the Nvim server
|
|
||||||
|:retab| :ret[ab] change tab size
|
|:retab| :ret[ab] change tab size
|
||||||
|:return| :retu[rn] return from a user function
|
|:return| :retu[rn] return from a user function
|
||||||
|:rewind| :rew[ind] go to the first file in the argument list
|
|:rewind| :rew[ind] go to the first file in the argument list
|
||||||
@@ -1667,7 +1663,6 @@ tag command action ~
|
|||||||
|:unabbreviate| :una[bbreviate] remove abbreviation
|
|:unabbreviate| :una[bbreviate] remove abbreviation
|
||||||
|:unhide| :unh[ide] open a window for each loaded file in the
|
|:unhide| :unh[ide] open a window for each loaded file in the
|
||||||
buffer list
|
buffer list
|
||||||
|:uniq| :uni[q] uniq lines
|
|
||||||
|:unlet| :unl[et] delete variable
|
|:unlet| :unl[et] delete variable
|
||||||
|:unlockvar| :unlo[ckvar] unlock variables
|
|:unlockvar| :unlo[ckvar] unlock variables
|
||||||
|:unmap| :unm[ap] remove mapping
|
|:unmap| :unm[ap] remove mapping
|
||||||
|
@@ -29,7 +29,7 @@ use "CTRL-V 003" to insert a CTRL-C. Note: When CTRL-V is mapped you can
|
|||||||
often use CTRL-Q instead |i_CTRL-Q|.
|
often use CTRL-Q instead |i_CTRL-Q|.
|
||||||
|
|
||||||
If you are working in a special language mode when inserting text, see the
|
If you are working in a special language mode when inserting text, see the
|
||||||
'langmap' option, 'langmap', on how to avoid switching this mode on and off
|
'langmap' option, |'langmap'|, on how to avoid switching this mode on and off
|
||||||
all the time.
|
all the time.
|
||||||
|
|
||||||
char action ~
|
char action ~
|
||||||
@@ -101,15 +101,13 @@ CTRL-N Find next keyword (see |i_CTRL-N|).
|
|||||||
CTRL-P Find previous keyword (see |i_CTRL-P|).
|
CTRL-P Find previous keyword (see |i_CTRL-P|).
|
||||||
|
|
||||||
CTRL-R {register} *i_CTRL-R*
|
CTRL-R {register} *i_CTRL-R*
|
||||||
Insert the contents of a register. Between typing CTRL-R and
|
Insert the contents of a register. Between typing CTRL-R and
|
||||||
the second character, '"' will be displayed to indicate that
|
the second character, '"' will be displayed to indicate that
|
||||||
you are expected to enter the name of a register. When used
|
you are expected to enter the name of a register.
|
||||||
with named or clipboard registers (A-Z,a-z,0-9,+) text is
|
The text is inserted as if you typed it, but mappings and
|
||||||
inserted literally like pasting with "p". For other registers,
|
|
||||||
the text is inserted as if you typed it, but mappings and
|
|
||||||
abbreviations are not used. If you have options like
|
abbreviations are not used. If you have options like
|
||||||
'textwidth', 'formatoptions', or 'autoindent' set, this will
|
'textwidth', 'formatoptions', or 'autoindent' set, this will
|
||||||
influence what will be inserted. This is different from what
|
influence what will be inserted. This is different from what
|
||||||
happens with the "p" command and pasting with the mouse.
|
happens with the "p" command and pasting with the mouse.
|
||||||
Special registers:
|
Special registers:
|
||||||
'"' the unnamed register, containing the text of
|
'"' the unnamed register, containing the text of
|
||||||
@@ -133,8 +131,6 @@ CTRL-R {register} *i_CTRL-R*
|
|||||||
special keys. E.g., you can use this to move
|
special keys. E.g., you can use this to move
|
||||||
the cursor up:
|
the cursor up:
|
||||||
CTRL-R ="\<Up>"
|
CTRL-R ="\<Up>"
|
||||||
you can use this to insert a register as
|
|
||||||
typed with CTRL-R =@reg.
|
|
||||||
Use CTRL-R CTRL-R to insert text literally.
|
Use CTRL-R CTRL-R to insert text literally.
|
||||||
When the result is a |List| the items are used
|
When the result is a |List| the items are used
|
||||||
as lines. They can have line breaks inside
|
as lines. They can have line breaks inside
|
||||||
@@ -273,17 +269,15 @@ The effect of the <BS>, CTRL-W, and CTRL-U depend on the 'backspace' option
|
|||||||
|
|
||||||
item action ~
|
item action ~
|
||||||
indent allow backspacing over autoindent
|
indent allow backspacing over autoindent
|
||||||
eol allow backspacing over line breaks (join lines)
|
eol allow backspacing over end-of-line (join lines)
|
||||||
start allow backspacing over the start of insert; CTRL-W and CTRL-U stop
|
start allow backspacing over the start position of insert; CTRL-W and
|
||||||
once at the start of insert.
|
CTRL-U stop once at the start position
|
||||||
nostop like start, except CTRL-W and CTRL-U do not stop at the start of
|
|
||||||
insert.
|
|
||||||
|
|
||||||
When 'backspace' is empty, Vi compatible backspacing is used. You cannot
|
When 'backspace' is empty, Vi compatible backspacing is used. You cannot
|
||||||
backspace over autoindent, before column 1 or before where insert started.
|
backspace over autoindent, before column 1 or before where insert started.
|
||||||
|
|
||||||
For backwards compatibility the values "0", "1", "2" and "3" are also allowed,
|
For backwards compatibility the values "0", "1", "2" and "3" are also allowed,
|
||||||
see 'backspace'.
|
see |'backspace'|.
|
||||||
|
|
||||||
If the 'backspace' option does contain "eol" and the cursor is in column 1
|
If the 'backspace' option does contain "eol" and the cursor is in column 1
|
||||||
when one of the three keys is used, the current line is joined with the
|
when one of the three keys is used, the current line is joined with the
|
||||||
@@ -516,7 +510,7 @@ paragraph, no matter where the cursor currently is. Or you can use Visual
|
|||||||
mode: hit "v", move to the end of the block, and type "gq". See also |gq|.
|
mode: hit "v", move to the end of the block, and type "gq". See also |gq|.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
4. 'expandtab', 'softtabstop' and 'smarttab' options *ins-expandtab*
|
4. 'expandtab', 'smarttab' and 'softtabstop' options *ins-expandtab*
|
||||||
|
|
||||||
If the 'expandtab' option is on, spaces will be used to fill the amount of
|
If the 'expandtab' option is on, spaces will be used to fill the amount of
|
||||||
whitespace of the tab. If you want to enter a real <Tab>, type CTRL-V first
|
whitespace of the tab. If you want to enter a real <Tab>, type CTRL-V first
|
||||||
@@ -527,6 +521,13 @@ number of characters in the line increases. Backspacing will delete one
|
|||||||
space at a time. The original character will be put back for only one space
|
space at a time. The original character will be put back for only one space
|
||||||
that you backspace over (the last one).
|
that you backspace over (the last one).
|
||||||
|
|
||||||
|
*ins-smarttab*
|
||||||
|
When the 'smarttab' option is on, a <Tab> inserts 'shiftwidth' positions at
|
||||||
|
the beginning of a line and 'tabstop' positions in other places. This means
|
||||||
|
that often spaces instead of a <Tab> character are inserted. When 'smarttab'
|
||||||
|
is off, a <Tab> always inserts 'tabstop' positions, and 'shiftwidth' is only
|
||||||
|
used for ">>" and the like.
|
||||||
|
|
||||||
*ins-softtabstop*
|
*ins-softtabstop*
|
||||||
When the 'softtabstop' option is non-zero, a <Tab> inserts 'softtabstop'
|
When the 'softtabstop' option is non-zero, a <Tab> inserts 'softtabstop'
|
||||||
positions, and a <BS> used to delete white space, will delete 'softtabstop'
|
positions, and a <BS> used to delete white space, will delete 'softtabstop'
|
||||||
@@ -541,13 +542,6 @@ the cursor. Otherwise you cannot always delete a single character before the
|
|||||||
cursor. You will have to delete 'softtabstop' characters first, and then type
|
cursor. You will have to delete 'softtabstop' characters first, and then type
|
||||||
extra spaces to get where you want to be.
|
extra spaces to get where you want to be.
|
||||||
|
|
||||||
*ins-smarttab*
|
|
||||||
When the 'smarttab' option is on, the <Tab> key indents by 'shiftwidth' if the
|
|
||||||
cursor is in leading whitespace. The <BS> key has the opposite effect. This
|
|
||||||
behaves as if 'softtabstop' were set to the value of 'shiftwidth'. This option
|
|
||||||
allows the user to set 'softtabstop' to a value other than 'shiftwidth' and
|
|
||||||
still use the <Tab> key for indentation.
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
5. Replace mode *Replace* *Replace-mode* *mode-replace*
|
5. Replace mode *Replace* *Replace-mode* *mode-replace*
|
||||||
|
|
||||||
@@ -605,7 +599,7 @@ In 'list' mode, Virtual Replace mode acts as if it was not in 'list' mode,
|
|||||||
unless "L" is in 'cpoptions'.
|
unless "L" is in 'cpoptions'.
|
||||||
|
|
||||||
Note that the only situations for which characters beyond the cursor should
|
Note that the only situations for which characters beyond the cursor should
|
||||||
appear to move are in List mode 'list', and occasionally when 'wrap' is set
|
appear to move are in List mode |'list'|, and occasionally when 'wrap' is set
|
||||||
(and the line changes length to become shorter or wider than the width of the
|
(and the line changes length to become shorter or wider than the width of the
|
||||||
screen). In other cases spaces may be inserted to avoid following characters
|
screen). In other cases spaces may be inserted to avoid following characters
|
||||||
to move.
|
to move.
|
||||||
@@ -634,8 +628,7 @@ Completion can be done for:
|
|||||||
10. User defined completion |i_CTRL-X_CTRL-U|
|
10. User defined completion |i_CTRL-X_CTRL-U|
|
||||||
11. omni completion |i_CTRL-X_CTRL-O|
|
11. omni completion |i_CTRL-X_CTRL-O|
|
||||||
12. Spelling suggestions |i_CTRL-X_s|
|
12. Spelling suggestions |i_CTRL-X_s|
|
||||||
13. completions from 'complete' |i_CTRL-N| |i_CTRL-P|
|
13. keywords in 'complete' |i_CTRL-N| |i_CTRL-P|
|
||||||
14. contents from registers |i_CTRL-X_CTRL-R|
|
|
||||||
|
|
||||||
Additionally, |i_CTRL-X_CTRL-Z| stops completion without changing the text.
|
Additionally, |i_CTRL-X_CTRL-Z| stops completion without changing the text.
|
||||||
|
|
||||||
@@ -645,9 +638,6 @@ and one of the CTRL-X commands. You exit CTRL-X mode by typing a key that is
|
|||||||
not a valid CTRL-X mode command. Valid keys are the CTRL-X command itself,
|
not a valid CTRL-X mode command. Valid keys are the CTRL-X command itself,
|
||||||
CTRL-N (next), and CTRL-P (previous).
|
CTRL-N (next), and CTRL-P (previous).
|
||||||
|
|
||||||
By default, the possible completions are showed in a menu and the first
|
|
||||||
completion is inserted into the text. This can be adjusted with 'completeopt'.
|
|
||||||
|
|
||||||
To get the current completion information, |complete_info()| can be used.
|
To get the current completion information, |complete_info()| can be used.
|
||||||
Also see the 'infercase' option if you want to adjust the case of the match.
|
Also see the 'infercase' option if you want to adjust the case of the match.
|
||||||
|
|
||||||
@@ -661,11 +651,10 @@ When completion is active you can use CTRL-E to stop it and go back to the
|
|||||||
originally typed text. The CTRL-E will not be inserted.
|
originally typed text. The CTRL-E will not be inserted.
|
||||||
|
|
||||||
*complete_CTRL-Y*
|
*complete_CTRL-Y*
|
||||||
When the popup menu is displayed, CTRL-Y stops completion and accepts the
|
When the popup menu is displayed you can use CTRL-Y to stop completion and
|
||||||
currently selected entry. Typing a space, Enter, or some other unprintable
|
accept the currently selected entry. The CTRL-Y is not inserted. Typing a
|
||||||
character will leave completion mode and insert that typed character. If you
|
space, Enter, or some other unprintable character will leave completion mode
|
||||||
want to use <Enter> to accept a completion item, use this mapping: >vim
|
and insert that typed character.
|
||||||
inoremap <expr> <cr> pumvisible() ? '<c-y>' : '<cr>'
|
|
||||||
|
|
||||||
When the popup menu is displayed there are a few more special keys, see
|
When the popup menu is displayed there are a few more special keys, see
|
||||||
|popupmenu-keys|.
|
|popupmenu-keys|.
|
||||||
@@ -1009,25 +998,6 @@ CTRL-X CTRL-V Guess what kind of item is in front of the cursor and
|
|||||||
completion, for example: >
|
completion, for example: >
|
||||||
:imap <Tab> <C-X><C-V>
|
:imap <Tab> <C-X><C-V>
|
||||||
|
|
||||||
Completing contents from registers *compl-register-words*
|
|
||||||
*i_CTRL-X_CTRL-R*
|
|
||||||
CTRL-X CTRL-R Guess what kind of item is in front of the cursor from
|
|
||||||
all registers and find the first match for it.
|
|
||||||
Further use of CTRL-R (without CTRL-X) will insert the
|
|
||||||
register content, see |i_CTRL-R|.
|
|
||||||
'ignorecase' applies to the matching.
|
|
||||||
|
|
||||||
CTRL-N Search forwards for next match. This match replaces
|
|
||||||
the previous one.
|
|
||||||
|
|
||||||
CTRL-P Search backwards for previous match. This match
|
|
||||||
replaces the previous one.
|
|
||||||
|
|
||||||
CTRL-X CTRL-R Further use of CTRL-X CTRL-R will copy the line
|
|
||||||
following the previous expansion in other contexts
|
|
||||||
unless a double CTRL-X is used (e.g. this switches
|
|
||||||
from completing register words to register contents).
|
|
||||||
|
|
||||||
User defined completion *compl-function*
|
User defined completion *compl-function*
|
||||||
|
|
||||||
Completion is done by a function that can be defined by the user with the
|
Completion is done by a function that can be defined by the user with the
|
||||||
@@ -1088,23 +1058,25 @@ CTRL-X s Locate the word in front of the cursor and find the
|
|||||||
previous one.
|
previous one.
|
||||||
|
|
||||||
|
|
||||||
Completing from different sources *compl-generic*
|
Completing keywords from different sources *compl-generic*
|
||||||
|
|
||||||
*i_CTRL-N*
|
*i_CTRL-N*
|
||||||
CTRL-N Find the next match for a word ending at the cursor,
|
CTRL-N Find next match for words that start with the
|
||||||
using the sources specified in the 'complete' option.
|
keyword in front of the cursor, looking in places
|
||||||
All sources complete from keywords, except functions,
|
specified with the 'complete' option. The found
|
||||||
which may complete from non-keyword. The matched
|
keyword is inserted in front of the cursor.
|
||||||
text is inserted before the cursor.
|
|
||||||
|
|
||||||
*i_CTRL-P*
|
*i_CTRL-P*
|
||||||
CTRL-P Same as CTRL-N, but find the previous match.
|
CTRL-P Find previous match for words that start with the
|
||||||
|
keyword in front of the cursor, looking in places
|
||||||
|
specified with the 'complete' option. The found
|
||||||
|
keyword is inserted in front of the cursor.
|
||||||
|
|
||||||
CTRL-N Search forward through the matches and insert the
|
CTRL-N Search forward for next matching keyword. This
|
||||||
next one.
|
keyword replaces the previous matching keyword.
|
||||||
|
|
||||||
CTRL-P Search backward through the matches and insert the
|
CTRL-P Search backwards for next matching keyword. This
|
||||||
previous one.
|
keyword replaces the previous matching keyword.
|
||||||
|
|
||||||
CTRL-X CTRL-N or
|
CTRL-X CTRL-N or
|
||||||
CTRL-X CTRL-P Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will
|
CTRL-X CTRL-P Further use of CTRL-X CTRL-N or CTRL-X CTRL-P will
|
||||||
@@ -1118,25 +1090,26 @@ Stop completion *compl-stop*
|
|||||||
CTRL-X CTRL-Z Stop completion without changing the text.
|
CTRL-X CTRL-Z Stop completion without changing the text.
|
||||||
|
|
||||||
|
|
||||||
AUTOCOMPLETION *ins-autocompletion*
|
AUTO-COMPLETION *compl-autocomplete*
|
||||||
|
|
||||||
Vim can display a completion menu as you type, similar to using |i_CTRL-N|,
|
To get LSP-driven auto-completion, see |lsp-completion|. To get basic
|
||||||
but triggered automatically. See 'autocomplete'. The menu items are collected
|
auto-completion without installing plugins or LSP, try this: >lua
|
||||||
from the sources listed in the 'complete' option, in order.
|
|
||||||
|
|
||||||
A decaying timeout keeps Vim responsive. Sources earlier in the 'complete'
|
|
||||||
list get more time (higher priority), but all sources receive at least a small
|
|
||||||
time slice.
|
|
||||||
|
|
||||||
This mode is fully compatible with other completion modes. You can invoke
|
|
||||||
any of them at any time by typing |CTRL-X|, which temporarily suspends
|
|
||||||
autocompletion. To use |i_CTRL-N| or |i_CTRL-X_CTRL-N| specifically, press
|
|
||||||
|CTRL-E| first to dismiss the popup menu (see |complete_CTRL-E|).
|
|
||||||
|
|
||||||
See also 'autocomplete', 'autocompletetimeout' and 'autocompletedelay'.
|
|
||||||
|
|
||||||
To get LSP-driven auto-completion, see |lsp-completion|.
|
|
||||||
|
|
||||||
|
local triggers = {'.'}
|
||||||
|
vim.api.nvim_create_autocmd('InsertCharPre', {
|
||||||
|
buffer = vim.api.nvim_get_current_buf(),
|
||||||
|
callback = function()
|
||||||
|
if vim.fn.pumvisible() == 1 or vim.fn.state('m') == 'm' then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local char = vim.v.char
|
||||||
|
if vim.list_contains(triggers, char) then
|
||||||
|
local key = vim.keycode('<C-x><C-n>')
|
||||||
|
vim.api.nvim_feedkeys(key, 'm', false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
<
|
||||||
|
|
||||||
FUNCTIONS FOR FINDING COMPLETIONS *complete-functions*
|
FUNCTIONS FOR FINDING COMPLETIONS *complete-functions*
|
||||||
|
|
||||||
@@ -1189,9 +1162,6 @@ For example, the function can contain this: >
|
|||||||
let matches = ... list of words ...
|
let matches = ... list of words ...
|
||||||
return {'words': matches, 'refresh': 'always'}
|
return {'words': matches, 'refresh': 'always'}
|
||||||
<
|
<
|
||||||
If looking for matches is time-consuming, |complete_check()| may be used to
|
|
||||||
maintain responsiveness.
|
|
||||||
|
|
||||||
*complete-items*
|
*complete-items*
|
||||||
Each list item can either be a string or a Dictionary. When it is a string it
|
Each list item can either be a string or a Dictionary. When it is a string it
|
||||||
is used as the completion. When it is a Dictionary it can contain these
|
is used as the completion. When it is a Dictionary it can contain these
|
||||||
@@ -1326,7 +1296,6 @@ use all space available.
|
|||||||
The 'pumwidth' option can be used to set a minimum width. The default is 15
|
The 'pumwidth' option can be used to set a minimum width. The default is 15
|
||||||
characters.
|
characters.
|
||||||
|
|
||||||
*compl-states*
|
|
||||||
There are three states:
|
There are three states:
|
||||||
1. A complete match has been inserted, e.g., after using CTRL-N or CTRL-P.
|
1. A complete match has been inserted, e.g., after using CTRL-N or CTRL-P.
|
||||||
2. A cursor key has been used to select another match. The match was not
|
2. A cursor key has been used to select another match. The match was not
|
||||||
|
@@ -89,7 +89,7 @@ To uninstall Nvim:
|
|||||||
- Scoop (Windows): `scoop uninstall neovim`
|
- Scoop (Windows): `scoop uninstall neovim`
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Sponsor Vim/Nvim development *sponsor*
|
Sponsor Vim/Nvim development *sponsor* *register*
|
||||||
|
|
||||||
Fixing bugs and adding new features takes a lot of time and effort. To show
|
Fixing bugs and adding new features takes a lot of time and effort. To show
|
||||||
your appreciation for the work and motivate developers to continue working on
|
your appreciation for the work and motivate developers to continue working on
|
||||||
@@ -605,7 +605,7 @@ status messages will only be used if an option is on: >
|
|||||||
command characters 'showcmd' on off
|
command characters 'showcmd' on off
|
||||||
cursor position 'ruler' off off
|
cursor position 'ruler' off off
|
||||||
|
|
||||||
The current mode is "-- INSERT --" or "-- REPLACE --", see 'showmode'. The
|
The current mode is "-- INSERT --" or "-- REPLACE --", see |'showmode'|. The
|
||||||
command characters are those that you typed but were not used yet.
|
command characters are those that you typed but were not used yet.
|
||||||
|
|
||||||
If you have a slow terminal you can switch off the status messages to speed
|
If you have a slow terminal you can switch off the status messages to speed
|
||||||
@@ -711,4 +711,5 @@ Arbitrary code registered via |:UpdateRemotePlugins|, that runs in a separate
|
|||||||
process and communicates with Nvim via the |api|.
|
process and communicates with Nvim via the |api|.
|
||||||
|
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:et:sw=4:ft=help:norl:
|
vim:tw=78:ts=8:et:sw=4:ft=help:norl:
|
||||||
|
@@ -140,4 +140,5 @@ A job may be killed at any time with the |jobstop()| function:
|
|||||||
<
|
<
|
||||||
Individual streams can be closed without killing the job, see |chanclose()|.
|
Individual streams can be closed without killing the job, see |chanclose()|.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||||
|
1632
runtime/doc/lsp.txt
1632
runtime/doc/lsp.txt
File diff suppressed because it is too large
Load Diff
@@ -376,7 +376,8 @@ strongly advised not to rely on undefined or implementation-defined behavior.
|
|||||||
==============================================================================
|
==============================================================================
|
||||||
COPYRIGHT
|
COPYRIGHT
|
||||||
|
|
||||||
Lua BitOp is Copyright (C) 2008-2025 Mike Pall.
|
Lua BitOp is Copyright (C) 2008-2012 Mike Pall.
|
||||||
Lua BitOp is free software, released under the MIT license.
|
Lua BitOp is free software, released under the MIT license.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
vim:tw=78:ts=4:sw=4:sts=4:et:ft=help:norl:
|
vim:tw=78:ts=4:sw=4:sts=4:et:ft=help:norl:
|
||||||
|
@@ -10,18 +10,19 @@
|
|||||||
==============================================================================
|
==============================================================================
|
||||||
Introduction *lua-guide*
|
Introduction *lua-guide*
|
||||||
|
|
||||||
This guide introduces the basics of everyday Lua usage for configuring and
|
This guide will go through the basics of using Lua in Nvim. It is not meant
|
||||||
controlling Nvim. It assumes some familiarity with the (non-Lua) basics of
|
to be a comprehensive encyclopedia of all available features, nor will it
|
||||||
Nvim (commands, options, mappings, autocommands), which are covered in the
|
detail all intricacies. Think of it as a survival kit -- the bare minimum
|
||||||
|
needed to know to comfortably get started on using Lua in Nvim.
|
||||||
|
|
||||||
|
An important thing to note is that this isn't a guide to the Lua language
|
||||||
|
itself. Rather, this is a guide on how to configure and modify Nvim through
|
||||||
|
the Lua language and the functions we provide to help with this. Take a look
|
||||||
|
at |luaref| and |lua-concepts| if you'd like to learn more about Lua itself.
|
||||||
|
Similarly, this guide assumes some familiarity with the basics of Nvim
|
||||||
|
(commands, options, mappings, autocommands), which are covered in the
|
||||||
|user-manual|.
|
|user-manual|.
|
||||||
|
|
||||||
This is not a comprehensive encyclopedia of all available features. Think of
|
|
||||||
it as a survival kit: the bare minimum needed to comfortably get started on
|
|
||||||
using Lua in Nvim.
|
|
||||||
|
|
||||||
See |lua-plugin| for guidance on developing Lua plugins.
|
|
||||||
See |luaref| and |lua-concepts| for details on the Lua programming language.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Some words on the API *lua-guide-api*
|
Some words on the API *lua-guide-api*
|
||||||
|
|
||||||
@@ -29,17 +30,16 @@ The purpose of this guide is to introduce the different ways of interacting
|
|||||||
with Nvim through Lua (the "API"). This API consists of three different
|
with Nvim through Lua (the "API"). This API consists of three different
|
||||||
layers:
|
layers:
|
||||||
|
|
||||||
1. The "Vim API" inherited from Vim: |Ex-commands| and |vimscript-functions|
|
1. The "Vim API" inherited from Vim: |Ex-commands| and |builtin-functions| as
|
||||||
as well as |user-function|s in Vimscript. These are accessed through
|
well as |user-function|s in Vimscript. These are accessed through |vim.cmd()|
|
||||||
|vim.cmd()| and |vim.fn| respectively, which are discussed under
|
and |vim.fn| respectively, which are discussed under |lua-guide-vimscript|
|
||||||
|lua-guide-vimscript| below.
|
below.
|
||||||
|
|
||||||
2. The "Nvim API" written in C for use in remote plugins and GUIs; see |api|.
|
2. The "Nvim API" written in C for use in remote plugins and GUIs; see |api|.
|
||||||
These functions are accessed through |vim.api|.
|
These functions are accessed through |vim.api|.
|
||||||
|
|
||||||
3. The "Lua API" written in and specifically for Lua. These are any other
|
3. The "Lua API" written in and specifically for Lua. These are any other
|
||||||
functions accessible through `vim.*` not mentioned already; see
|
functions accessible through `vim.*` not mentioned already; see |lua-stdlib|.
|
||||||
|lua-stdlib|.
|
|
||||||
|
|
||||||
This distinction is important, as API functions inherit behavior from their
|
This distinction is important, as API functions inherit behavior from their
|
||||||
original layer: For example, Nvim API functions always need all arguments to
|
original layer: For example, Nvim API functions always need all arguments to
|
||||||
@@ -121,6 +121,7 @@ Let's assume you have the following directory structure:
|
|||||||
|-- syntax/
|
|-- syntax/
|
||||||
|-- init.vim
|
|-- init.vim
|
||||||
<
|
<
|
||||||
|
|
||||||
Then the following Lua code will load `myluamodule.lua`:
|
Then the following Lua code will load `myluamodule.lua`:
|
||||||
>lua
|
>lua
|
||||||
require("myluamodule")
|
require("myluamodule")
|
||||||
@@ -133,6 +134,7 @@ Similarly, loading `other_modules/anothermodule.lua` is done via
|
|||||||
-- or
|
-- or
|
||||||
require('other_modules.anothermodule')
|
require('other_modules.anothermodule')
|
||||||
<
|
<
|
||||||
|
|
||||||
Note how "submodules" are just subdirectories; the `.` is equivalent to the
|
Note how "submodules" are just subdirectories; the `.` is equivalent to the
|
||||||
path separator `/` (even on Windows).
|
path separator `/` (even on Windows).
|
||||||
|
|
||||||
@@ -164,7 +166,7 @@ the cache manually first:
|
|||||||
<
|
<
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
See also:
|
See also:
|
||||||
• |lua-module-load|: how `require()` finds modules
|
• |lua-module-load|
|
||||||
• |pcall()|
|
• |pcall()|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
@@ -223,7 +225,7 @@ Vimscript are automatically converted:
|
|||||||
|
|
||||||
vim.fn.jobstart('ls', { on_stdout = print_stdout })
|
vim.fn.jobstart('ls', { on_stdout = print_stdout })
|
||||||
<
|
<
|
||||||
This works for both |vimscript-functions| and |user-function|s.
|
This works for both |builtin-functions| and |user-function|s.
|
||||||
|
|
||||||
Note that hashes (`#`) are not valid characters for identifiers in Lua, so,
|
Note that hashes (`#`) are not valid characters for identifiers in Lua, so,
|
||||||
e.g., |autoload| functions have to be called with this syntax:
|
e.g., |autoload| functions have to be called with this syntax:
|
||||||
@@ -232,9 +234,10 @@ e.g., |autoload| functions have to be called with this syntax:
|
|||||||
<
|
<
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
See also:
|
See also:
|
||||||
• |vimscript-functions|: descriptions of all Vimscript functions
|
• |builtin-functions|: alphabetic list of all Vimscript functions
|
||||||
• |function-list|: Vimscript functions grouped by topic
|
• |function-list|: list of all Vimscript functions grouped by topic
|
||||||
• |:runtime|: run all Lua scripts matching a pattern in |'runtimepath'|
|
• |:runtime|: run all Lua scripts matching a pattern in |'runtimepath'|
|
||||||
|
• |package.path|: list of all paths searched by `require()`
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
Variables *lua-guide-variables*
|
Variables *lua-guide-variables*
|
||||||
@@ -527,6 +530,7 @@ Examples:
|
|||||||
callback = function() print("My Plugin Works!") end,
|
callback = function() print("My Plugin Works!") end,
|
||||||
})
|
})
|
||||||
<
|
<
|
||||||
|
|
||||||
Nvim will always call a Lua function with a single table containing information
|
Nvim will always call a Lua function with a single table containing information
|
||||||
about the triggered autocommand. The most useful keys are
|
about the triggered autocommand. The most useful keys are
|
||||||
• `match`: a string that matched the `pattern` (see |<amatch>|)
|
• `match`: a string that matched the `pattern` (see |<amatch>|)
|
||||||
|
@@ -1,313 +0,0 @@
|
|||||||
*lua-plugin.txt* Nvim
|
|
||||||
|
|
||||||
NVIM REFERENCE MANUAL
|
|
||||||
|
|
||||||
Guide to developing Lua plugins for Nvim
|
|
||||||
|
|
||||||
|
|
||||||
Type |gO| to see the table of contents.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Introduction *lua-plugin*
|
|
||||||
|
|
||||||
This document provides guidance for developing Nvim Lua plugins.
|
|
||||||
|
|
||||||
See |lua-guide| for guidance on using Lua to configure and operate Nvim.
|
|
||||||
See |luaref| and |lua-concepts| for details on the Lua programming language.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Creating your first plugin *lua-plugin-new*
|
|
||||||
|
|
||||||
Any Vimscript or Lua code file that lives in the right directory,
|
|
||||||
automatically is a "plugin". There's no manifest or "registration" step.
|
|
||||||
|
|
||||||
You can try it right now:
|
|
||||||
|
|
||||||
1. Visit your config directory: >
|
|
||||||
:exe 'edit' stdpath('config')
|
|
||||||
<
|
|
||||||
2. Create a `plugin/foo.lua` file in there.
|
|
||||||
3. Add something to it, like: >lua
|
|
||||||
vim.print('Hello World')
|
|
||||||
<
|
|
||||||
4. Start `nvim` and notice that it prints "Hello World" in the messages area.
|
|
||||||
Check `:messages` if you don't see it.
|
|
||||||
|
|
||||||
Besides `plugin/foo.lua`, which is always run at startup, you can define Lua
|
|
||||||
modules in the `lua/` directory. Those modules aren't loaded until your
|
|
||||||
`plugin/foo.lua`, or the user, calls `require(…)`.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Type safety *lua-plugin-type-safety*
|
|
||||||
|
|
||||||
Lua, as a dynamically typed language, is great for configuration. It provides
|
|
||||||
virtually immediate feedback.
|
|
||||||
But for larger projects, this can be a double-edged sword, leaving your plugin
|
|
||||||
susceptible to unexpected bugs at the wrong time.
|
|
||||||
|
|
||||||
You can leverage LuaCATS or "emmylua" annotations https://luals.github.io/wiki/annotations/
|
|
||||||
along with lua-language-server ("LuaLS") https://luals.github.io/ to catch
|
|
||||||
potential bugs in your CI before your plugin's users do. The Nvim codebase
|
|
||||||
uses these annotations extensively.
|
|
||||||
|
|
||||||
TOOLS
|
|
||||||
|
|
||||||
- lua-typecheck-action https://github.com/marketplace/actions/lua-typecheck-action
|
|
||||||
- lua-language-server https://luals.github.io
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Keymaps *lua-plugin-keymaps*
|
|
||||||
|
|
||||||
Avoid creating excessive keymaps automatically. Doing so can conflict with
|
|
||||||
user |mapping|s.
|
|
||||||
|
|
||||||
NOTE: An example for uncontroversial keymaps are buffer-local |mapping|s for
|
|
||||||
specific file types or floating windows, or <Plug> mappings.
|
|
||||||
|
|
||||||
A common approach to allow keymap configuration is to define a declarative DSL
|
|
||||||
https://en.wikipedia.org/wiki/Domain-specific_language via a `setup` function.
|
|
||||||
|
|
||||||
However, doing so means that
|
|
||||||
|
|
||||||
- You will have to implement and document it yourself.
|
|
||||||
- Users will likely face inconsistencies if another plugin has a slightly
|
|
||||||
different DSL.
|
|
||||||
- |init.lua| scripts that call such a `setup` function may throw an error if
|
|
||||||
the plugin is not installed or disabled.
|
|
||||||
|
|
||||||
As an alternative, you can provide |<Plug>| mappings to allow users to define
|
|
||||||
their own keymaps with |vim.keymap.set()|.
|
|
||||||
|
|
||||||
- This requires one line of code in user configs.
|
|
||||||
- Even if your plugin is not installed or disabled, creating the keymap won't
|
|
||||||
throw an error.
|
|
||||||
|
|
||||||
Another option is to simply expose a Lua function or |user-commands|.
|
|
||||||
|
|
||||||
Some benefits of |<Plug>| mappings are that you can
|
|
||||||
|
|
||||||
- Enforce options like `expr = true`.
|
|
||||||
- Use |vim.keymap|'s built-in mode handling to expose functionality only for
|
|
||||||
specific |map-modes|.
|
|
||||||
- Handle different |map-modes| differently with a single mapping, without
|
|
||||||
adding mode checks to the underlying implementation.
|
|
||||||
- Detect user-defined mappings through |hasmapto()| before creating defaults.
|
|
||||||
|
|
||||||
Some benefits of exposing a Lua function are:
|
|
||||||
|
|
||||||
- Extensibility, if the function takes an options table as an argument.
|
|
||||||
- A cleaner UX, if there are many options and enumerating all combinations
|
|
||||||
of options would result in a lot of |<Plug>| mappings.
|
|
||||||
|
|
||||||
NOTE: If your function takes an options table, users may still benefit
|
|
||||||
from |<Plug>| mappings for the most common combinations.
|
|
||||||
|
|
||||||
KEYMAP EXAMPLE
|
|
||||||
|
|
||||||
In your plugin:
|
|
||||||
>lua
|
|
||||||
vim.keymap.set('n', '<Plug>(SayHello)', function()
|
|
||||||
print('Hello from normal mode')
|
|
||||||
end)
|
|
||||||
|
|
||||||
vim.keymap.set('v', '<Plug>(SayHello)', function()
|
|
||||||
print('Hello from visual mode')
|
|
||||||
end)
|
|
||||||
<
|
|
||||||
In the user's config:
|
|
||||||
>lua
|
|
||||||
vim.keymap.set({'n', 'v'}, '<leader>h', '<Plug>(SayHello)')
|
|
||||||
<
|
|
||||||
==============================================================================
|
|
||||||
Initialization *lua-plugin-init*
|
|
||||||
|
|
||||||
Newcomers to Lua plugin development will often put all initialization logic in
|
|
||||||
a single `setup` function, which takes a table of options.
|
|
||||||
If you do this, users will be forced to call this function in order to use
|
|
||||||
your plugin, even if they are happy with the default configuration.
|
|
||||||
|
|
||||||
Strictly separated configuration and smart initialization allow your plugin to
|
|
||||||
work out of the box.
|
|
||||||
|
|
||||||
NOTE: A well designed plugin has minimal impact on startup time. See also
|
|
||||||
|lua-plugin-lazy|.
|
|
||||||
|
|
||||||
Common approaches to a strictly separated configuration are:
|
|
||||||
|
|
||||||
- A Lua function, e.g. `setup(opts)` or `configure(opts)`, which only overrides the
|
|
||||||
default configuration and does not contain any initialization logic.
|
|
||||||
- A Vimscript compatible table (e.g. in the |vim.g| or |vim.b| namespace) that your
|
|
||||||
plugin reads from and validates at initialization time.
|
|
||||||
See also |lua-vim-variables|.
|
|
||||||
|
|
||||||
Typically, automatic initialization logic is done in a |plugin| or |ftplugin|
|
|
||||||
script. See also |'runtimepath'|.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Lazy loading *lua-plugin-lazy*
|
|
||||||
|
|
||||||
Some users like to micro-manage "lazy loading" of plugins by explicitly
|
|
||||||
configuring which commands and key mappings load the plugin.
|
|
||||||
|
|
||||||
Your plugin should not depend on every user micro-managing their configuration
|
|
||||||
in such a way. Nvim has a mechanism for every plugin to do its own implicit
|
|
||||||
lazy-loading (in Vimscript it's called |autoload|), via `autoload/`
|
|
||||||
(Vimscript) and `lua/` (Lua). Plugin authors can provide "lazy loading" by
|
|
||||||
providing a `plugin/<name>.lua` file which defines their commands and
|
|
||||||
keymappings. This file should be small, and should not eagerly `require()` the
|
|
||||||
rest of your plugin. Commands and mappings should do the `require()`.
|
|
||||||
|
|
||||||
Guidance:
|
|
||||||
|
|
||||||
- Plugins should arrange their "lazy" behavior once, instead of expecting every user to micromanage it.
|
|
||||||
- Keep `plugin/<name>.lua` small, avoid eagerly calling `require()` on modules
|
|
||||||
until a command or mapping is actually used.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Defer require() calls *lua-plugin-defer-require*
|
|
||||||
|
|
||||||
`plugin/<name>.lua` scripts (|plugin|) are eagerly run at startup; this is
|
|
||||||
intentional, so that plugins can setup the (minimal) commands and keymappings
|
|
||||||
that users will use to invoke the plugin. This also means these "plugin/"
|
|
||||||
files should NOT eagerly `require` Lua modules.
|
|
||||||
|
|
||||||
For example, instead of:
|
|
||||||
>lua
|
|
||||||
local foo = require('foo')
|
|
||||||
vim.api.nvim_create_user_command('MyCommand', function()
|
|
||||||
foo.do_something()
|
|
||||||
end, {
|
|
||||||
-- ...
|
|
||||||
})
|
|
||||||
<
|
|
||||||
which calls `require('foo')` as soon as the module is loaded, you can
|
|
||||||
lazy-load it by moving the `require` into the command's implementation:
|
|
||||||
>lua
|
|
||||||
vim.api.nvim_create_user_command('MyCommand', function()
|
|
||||||
local foo = require('foo')
|
|
||||||
foo.do_something()
|
|
||||||
end, {
|
|
||||||
-- ...
|
|
||||||
})
|
|
||||||
<
|
|
||||||
Likewise, if a plugin uses a Lua module as an entrypoint, it should
|
|
||||||
defer `require` calls too.
|
|
||||||
|
|
||||||
NOTE: For a Vimscript alternative to `require`, see |autoload|.
|
|
||||||
|
|
||||||
NOTE: If you are worried about eagerly creating user commands, autocommands or
|
|
||||||
keymaps at startup: Plugin managers that provide abstractions for lazy-loading
|
|
||||||
plugins on such events do the same amount of work. There is no performance
|
|
||||||
benefit for users to define lazy-loading entrypoints in their configuration
|
|
||||||
instead of plugins defining it in `plugin/<name>.lua`.
|
|
||||||
|
|
||||||
NOTE: You can use |--startuptime| to |profile| the impact a plugin has on
|
|
||||||
startup time.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Filetype-specific functionality *lua-plugin-filetype*
|
|
||||||
|
|
||||||
Consider making use of 'filetype' for any functionality that is specific to
|
|
||||||
a filetype, by putting the initialization logic in a `ftplugin/{filetype}.lua`
|
|
||||||
script.
|
|
||||||
|
|
||||||
FILETYPE EXAMPLE
|
|
||||||
|
|
||||||
A plugin tailored to Rust development might have initialization in
|
|
||||||
`ftplugin/rust.lua`:
|
|
||||||
>lua
|
|
||||||
if not vim.g.loaded_my_rust_plugin then
|
|
||||||
-- Initialize
|
|
||||||
end
|
|
||||||
-- NOTE: Using `vim.g.loaded_` prevents the plugin from initializing twice
|
|
||||||
-- and allows users to prevent plugins from loading
|
|
||||||
-- (in both Lua and Vimscript).
|
|
||||||
vim.g.loaded_my_rust_plugin = true
|
|
||||||
|
|
||||||
local bufnr = vim.api.nvim_get_current_buf()
|
|
||||||
-- do something specific to this buffer,
|
|
||||||
-- e.g. add a |<Plug>| mapping or create a command
|
|
||||||
vim.keymap.set('n', '<Plug>(MyPluginBufferAction)', function()
|
|
||||||
print('Hello')
|
|
||||||
end, { buffer = bufnr, })
|
|
||||||
<
|
|
||||||
==============================================================================
|
|
||||||
Configuration *lua-plugin-config*
|
|
||||||
|
|
||||||
Once you have merged the default configuration with the user's config, you
|
|
||||||
should validate configs.
|
|
||||||
|
|
||||||
Validations could include:
|
|
||||||
|
|
||||||
- Correct types, see |vim.validate()|
|
|
||||||
- Unknown fields in the user config (e.g. due to typos).
|
|
||||||
This can be tricky to implement, and may be better suited for a |health|
|
|
||||||
check, to reduce overhead.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Troubleshooting *lua-plugin-troubleshooting*
|
|
||||||
|
|
||||||
While developing a plugin, you can use the |:restart| command to see the
|
|
||||||
result of code changes in your plugin.
|
|
||||||
|
|
||||||
HEALTH
|
|
||||||
|
|
||||||
Nvim's "health" framework gives plugins a simple way to report status checks
|
|
||||||
to users. See |health-dev| for an example.
|
|
||||||
|
|
||||||
Basically, this just means your plugin will have a `lua/{plugin}/health.lua`
|
|
||||||
file. |:checkhealth| will automatically find this file when it runs.
|
|
||||||
|
|
||||||
Some things to validate:
|
|
||||||
|
|
||||||
- User configuration
|
|
||||||
- Proper initialization
|
|
||||||
- Presence of Lua dependencies (e.g. other plugins)
|
|
||||||
- Presence of external dependencies
|
|
||||||
|
|
||||||
MINIMAL CONFIG TEMPLATE
|
|
||||||
|
|
||||||
It can be useful to provide a template for a minimal configuration, along with
|
|
||||||
a guide on how to use it to reproduce issues.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Versioning and releases *lua-plugin-versioning*
|
|
||||||
|
|
||||||
Consider:
|
|
||||||
|
|
||||||
- Use |vim.deprecate()| or a `---@deprecate` annotation when you need to
|
|
||||||
communicate a (future) breaking change or discouraged practice.
|
|
||||||
- Using SemVer https://semver.org/ tags and releases to properly communicate
|
|
||||||
bug fixes, new features, and breaking changes.
|
|
||||||
- Automating versioning and releases in CI.
|
|
||||||
- Publishing to luarocks https://luarocks.org, especially if your plugin
|
|
||||||
has dependencies or components that need to be built; or if it could be a
|
|
||||||
dependency for another plugin.
|
|
||||||
|
|
||||||
FURTHER READING
|
|
||||||
|
|
||||||
- Luarocks ❤️ Nvim https://github.com/nvim-neorocks/sample-luarocks-plugin
|
|
||||||
|
|
||||||
VERSIONING TOOLS
|
|
||||||
|
|
||||||
- luarocks-tag-release
|
|
||||||
https://github.com/marketplace/actions/luarocks-tag-release
|
|
||||||
- release-please-action
|
|
||||||
https://github.com/marketplace/actions/release-please-action
|
|
||||||
- semantic-release
|
|
||||||
https://github.com/semantic-release/semantic-release
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Documentation *lua-plugin-doc*
|
|
||||||
|
|
||||||
Provide vimdoc (see |help-writing|), so that users can read your plugin's
|
|
||||||
documentation in Nvim, by entering `:h {plugin}` in |command-mode|. The
|
|
||||||
help-tags (the right-aligned "search keywords" in the help documents) are
|
|
||||||
regenerated using the |:helptags| command.
|
|
||||||
|
|
||||||
DOCUMENTATION TOOLS
|
|
||||||
|
|
||||||
- panvimdoc https://github.com/kdheepak/panvimdoc
|
|
||||||
|
|
||||||
|
|
||||||
vim:tw=78:ts=8:sw=4:sts=4:et:ft=help:norl:
|
|
3414
runtime/doc/lua.txt
3414
runtime/doc/lua.txt
File diff suppressed because it is too large
Load Diff
@@ -1654,8 +1654,8 @@ lua_Alloc *lua_Alloc*
|
|||||||
`NULL` if and only if it cannot fill the request. When `nsize` is not
|
`NULL` if and only if it cannot fill the request. When `nsize` is not
|
||||||
zero and `osize` is zero, the allocator should behave like `malloc`.
|
zero and `osize` is zero, the allocator should behave like `malloc`.
|
||||||
When `nsize` and `osize` are not zero, the allocator behaves like
|
When `nsize` and `osize` are not zero, the allocator behaves like
|
||||||
`realloc`. Lua assumes that the allocator never fails when
|
`realloc`. Lua assumes that the allocator never fails when `osize >=
|
||||||
`osize >= nsize`.
|
nsize`.
|
||||||
|
|
||||||
Here is a simple implementation for the allocator function. It is used
|
Here is a simple implementation for the allocator function. It is used
|
||||||
in the auxiliary library by `luaL_newstate` (see
|
in the auxiliary library by `luaL_newstate` (see
|
||||||
@@ -3567,8 +3567,8 @@ collectgarbage({opt} [, {arg}]) *collectgarbage()*
|
|||||||
`true` if the step finished a collection cycle.
|
`true` if the step finished a collection cycle.
|
||||||
`"setpause"` sets {arg} /100 as the new value for the `pause` of
|
`"setpause"` sets {arg} /100 as the new value for the `pause` of
|
||||||
the collector (see |lua-gc|).
|
the collector (see |lua-gc|).
|
||||||
`"setstepmul"` sets {arg} /100 as the new value for the
|
`"setstepmul"` sets {arg} /100 as the new value for the `step
|
||||||
`step multiplier` of the collector (see |lua-gc|).
|
multiplier` of the collector (see |lua-gc|).
|
||||||
|
|
||||||
dofile({filename}) *dofile()*
|
dofile({filename}) *dofile()*
|
||||||
Opens the named file and executes its contents as a Lua chunk. When
|
Opens the named file and executes its contents as a Lua chunk. When
|
||||||
@@ -4785,8 +4785,8 @@ debug.sethook([{thread},] {hook}, {mask} [, {count}]) *debug.sethook()*
|
|||||||
When called without arguments, the `debug.sethook` turns off the hook.
|
When called without arguments, the `debug.sethook` turns off the hook.
|
||||||
|
|
||||||
When the hook is called, its first parameter is a string describing
|
When the hook is called, its first parameter is a string describing
|
||||||
the event that triggered its call: `"call"`, `"return"` (or
|
the event that triggered its call: `"call"`, `"return"` (or `"tail
|
||||||
`"tail return"`), `"line"`, and `"count"`. For line events, the hook also
|
return"`), `"line"`, and `"count"`. For line events, the hook also
|
||||||
gets the new line number as its second parameter. Inside a hook, you
|
gets the new line number as its second parameter. Inside a hook, you
|
||||||
can call `getinfo` with level 2 to get more information about the
|
can call `getinfo` with level 2 to get more information about the
|
||||||
running function (level 0 is the `getinfo` function, and level 1 is
|
running function (level 0 is the `getinfo` function, and level 1 is
|
||||||
@@ -4885,4 +4885,5 @@ Christian Habermann's CRefVim project
|
|||||||
Adapted for bundled Nvim documentation; the original plugin can be found at
|
Adapted for bundled Nvim documentation; the original plugin can be found at
|
||||||
https://www.vim.org/scripts/script.php?script_id=1291
|
https://www.vim.org/scripts/script.php?script_id=1291
|
||||||
|
|
||||||
vim:tw=78:ts=4:ft=help:norl:et
|
------------------------------------------------------------------------------
|
||||||
|
vi:tw=78:ts=4:ft=help:norl:et
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user