This commit is contained in:
Justin M. Keyes
2026-04-18 15:38:59 -04:00
committed by GitHub
parent 97caa88972
commit 54398c5874
26 changed files with 470 additions and 311 deletions
+7 -8
View File
@@ -7,16 +7,15 @@ body:
attributes: attributes:
value: | value: |
*Before reporting:* *Before reporting:*
- Confirm the problem is reproducible on [**master**](https://github.com/neovim/neovim/releases/nightly) or [**latest stable**](https://github.com/neovim/neovim/releases/stable) release - Confirm the problem is reproducible in the [latest **nightly** release](https://github.com/neovim/neovim/releases/nightly).
- Run `make distclean` when encountering build issues - Run `make distclean` when encountering build issues.
- Search [existing issues](https://github.com/neovim/neovim/issues?q=is%3Aissue%20is%3Aopen%20type%3ABug) (including [closed](https://github.com/neovim/neovim/issues?q=is%3Aissue%20is%3Aclosed%20type%3ABug)) - Search [existing issues](https://github.com/neovim/neovim/issues?q=is%3Aissue%20is%3Aopen%20type%3ABug) (including [closed](https://github.com/neovim/neovim/issues?q=is%3Aissue%20is%3Aclosed%20type%3ABug))
- Read the [FAQ](https://neovim.io/doc/user/faq.html) and ["Reporting Problems" in CONTRIBUTING.md](https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#reporting-problems). - Read the [FAQ](https://neovim.io/doc/user/faq/) and ["Reporting Problems" in CONTRIBUTING.md](https://github.com/neovim/neovim/blob/master/CONTRIBUTING.md#reporting-problems).
- Usage or "How to" questions will be closed, use [Discussions](https://github.com/neovim/neovim/discussions) or [stackoverflow](https://vi.stackexchange.com/) instead.
Usage or "How to" questions belong on [stackoverflow](https://vi.stackexchange.com/) and will be closed.
- type: textarea - type: textarea
attributes: attributes:
label: "Problem" label: "Problem"
description: "Describe the current behavior. May include logs, images, or videos." description: "Describe the problem concisely. May include logs, images, or videos."
validations: validations:
required: true required: true
- type: textarea - type: textarea
@@ -24,10 +23,10 @@ body:
label: "Steps to reproduce" label: "Steps to reproduce"
description: | description: |
- For build failures: list the exact steps including CMake flags (if any). - For build failures: list the exact steps including CMake flags (if any).
- If the bug pertains to crashing (or segfault), please include a [stacktrace](https://neovim.io/doc/user/dev_tools.html#dev-tools-backtrace). - If the bug is a crash/segfault, please include a [stacktrace](https://neovim.io/doc/user/dev_tools/#dev-tools-backtrace).
- For startup or shell-related problems: try `env -i TERM=ansi-256color "$(which nvim)"`. - For startup or shell-related problems: try `env -i TERM=ansi-256color "$(which nvim)"`.
- Use the provided [minimal reproduction template](https://github.com/neovim/neovim/blob/master/contrib/minimal.lua) to create a minimal configuration. After you fill it out with necessary information, run with `nvim --clean -u minimal.lua`. - Use the provided [minimal reproduction template](https://github.com/neovim/neovim/blob/master/contrib/minimal.lua) to create a minimal configuration. After you fill it out with necessary information, run with `nvim --clean -u minimal.lua`.
- Please do **not** include a package manager in the reproduction steps. - Do **not** include a package manager in the reproduction steps.
placeholder: | placeholder: |
nvim --clean nvim --clean
:edit foo :edit foo
+1 -1
View File
@@ -23,7 +23,7 @@ ${NVIM_VERSION}
2. Run the MSI 2. Run the MSI
3. Run `nvim.exe` in your terminal 3. Run `nvim.exe` in your terminal
Note: On Windows "Server" you may need to [install vcruntime140.dll](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170). Note: On Windows "Server" you may need to [install `vcruntime*.dll`](https://neovim.io/doc/install/#windows).
### macOS (x86_64) ### macOS (x86_64)
+27 -30
View File
@@ -36,57 +36,54 @@ Windows 8+ is required. Windows 7 or older is not supported.
### [Winget](https://docs.microsoft.com/en-us/windows/package-manager/winget/) ### [Winget](https://docs.microsoft.com/en-us/windows/package-manager/winget/)
- **Release:** `winget install Neovim.Neovim` - **Release:** `winget install Neovim.Neovim`
- **Nightly:** [Not supported by winget](https://github.com/neovim/neovim/issues/38585)
### [Chocolatey](https://chocolatey.org) ### [Chocolatey](https://chocolatey.org)
- **Latest Release:** `choco install neovim` (use -y for automatically skipping confirmation messages) - **Release:** `choco install neovim` (use -y for automatically skipping confirmation messages)
- **Development (pre-release):** `choco install neovim --pre` - **Nightly:** `choco install neovim --pre`
### [Scoop](https://scoop.sh/) ### [Scoop](https://scoop.sh/)
```bash ```bash
scoop bucket add main scoop bucket add main
scoop install neovim scoop install neovim
``` ```
- **Release:** `scoop install neovim`
Several Neovim GUIs are available from scoop (extras): [scoop.sh/#/apps?q=neovim](https://scoop.sh/#/apps?q=neovim) Several Neovim GUIs are available from scoop (extras): [scoop.sh/#/apps?q=neovim](https://scoop.sh/#/apps?q=neovim)
### Pre-built archives ### MSI
If you are missing `VCRUNTIME170.dll`, install the [Visual Studio C++ redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist) (choose x86_64 or x86 depending on your system). > [!TIP]
- Hint: if you have scoop, try: `scoop install vcredist` > If you are missing `VCRUNTIME170.dll`, install the [Visual Studio C++ redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist) (choose x86_64 or x86 depending on your system).
> If you have scoop, try: `scoop install vcredist`.
**MSI** You can use this powershell script to install the MSI from the [releases page](https://github.com/neovim/neovim/releases):
For x86_64: - For x86_64:
```pwsh ```pwsh
iwr -Uri "https://github.com/neovim/neovim/releases/download/nightly/nvim-win64.msi" -OutFile nvim-win64.msi iwr -Uri "https://github.com/neovim/neovim/releases/download/nightly/nvim-win64.msi" -OutFile nvim-win64.msi
msiexec /i nvim-win64.msi /passive msiexec /i nvim-win64.msi /passive
rm nvim-win64.msi rm nvim-win64.msi
``` ```
- For arm64:
```pwsh
iwr -Uri "https://github.com/neovim/neovim/releases/download/nightly/nvim-win-arm64.msi" -OutFile nvim-win-arm64.msi
msiexec /i nvim-win-arm64.msi /passive
rm nvim-win-arm64.msi
```
For arm64: ### Zip
```pwsh
iwr -Uri "https://github.com/neovim/neovim/releases/download/nightly/nvim-win-arm64.msi" -OutFile nvim-win-arm64.msi
msiexec /i nvim-win-arm64.msi /passive
rm nvim-win-arm64.msi
```
**Zip**
1. Choose a package (**nvim-winXX.zip**) from the [releases page](https://github.com/neovim/neovim/releases). 1. Choose a package (**nvim-winXX.zip**) from the [releases page](https://github.com/neovim/neovim/releases).
2. Unzip the package. Any location is fine, administrator privileges are _not_ required. 2. Unzip the package. Any location is fine, administrator privileges are _not_ required.
- `$VIMRUNTIME` will be set to that location automatically. - `$VIMRUNTIME` will be set to that location automatically.
3. Run `nvim.exe` from a terminal. 3. Run `nvim.exe` from a terminal.
4. (Optional) Add the `bin` folder (e.g. `C:/Program Files/nvim/bin`) to your PATH.
This makes it easy to run `nvim` from any directory.
**Optional** steps: ### Optional steps
- If Installing from a zip package, add the `bin` folder (e.g. `C:\Program Files\nvim\bin`) to your PATH.
- This makes it easy to run `nvim` from anywhere.
- If `:set spell` does not work, create the `%LOCALAPPDATA%/nvim-data/site/spell` folder.
You can then copy your spell files over (for English, located
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.spl) and
[here](https://github.com/vim/vim/blob/master/runtime/spell/en.utf-8.sug));
- For Python plugins you need the `pynvim` module. Installation via uv - For Python plugins you need the `pynvim` module. Installation via uv
(https://docs.astral.sh/uv/) is recommended; the `--upgrade` switch ensures (https://docs.astral.sh/uv/) is recommended; the `--upgrade` switch ensures
installation of the latest version: installation of the latest version:
@@ -94,7 +91,7 @@ rm nvim-win-arm64.msi
uv tool install --upgrade pynvim uv tool install --upgrade pynvim
``` ```
- Run `:checkhealth` and read `:help provider-python` for more details. - 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.
## macOS / OS X ## macOS / OS X
@@ -473,7 +470,7 @@ make CMAKE_BUILD_TYPE=Release
sudo make install sudo make install
``` ```
For Unix-like systems this installs Neovim to `/usr/local`, while for Windows to `C:\Program Files`. Note, however, that this can complicate uninstallation. The following example avoids this by isolating an installation under `$HOME/neovim`: For Unix-like systems this installs Neovim to `/usr/local`, while for Windows to `C:/Program Files`. Note, however, that this can complicate uninstallation. The following example avoids this by isolating an installation under `$HOME/neovim`:
```bash ```bash
rm -r build/ # clear the CMake cache rm -r build/ # clear the CMake cache
make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim" make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$HOME/neovim"
+10 -12
View File
@@ -3971,18 +3971,16 @@ nvim_open_win({buf}, {enter}, {config}) *nvim_open_win()*
like |:topleft|, |:botright|), the relative window for a like |:topleft|, |:botright|), the relative window for a
`relative="win"` float, or just the target tab page `relative="win"` float, or just the target tab page
(inferred from the window) for others. (inferred from the window) for others.
• zindex: Stacking order. floats with higher `zindex` go on • zindex: (positive integer, default: 50) Stacking order.
top on floats with lower indices. Must be larger than Floats with higher `zindex` overlay floats with lower
zero. The following screen elements have hard-coded indices. Below 100 is recommended, unless there is a good
z-indices: reason to overshadow builtin elements. The cursor is
• 100: insert completion popupmenu dimmed if an unfocused float above the cursor exceeds the
• 200: message scrollback zindex of the current window by 50. These screen elements
• 250: cmdline completion popupmenu (when have hard-coded z-indices:
wildoptions+=pum) The default value for floats are 50. • 100: |ins-completion-menu| popupmenu
In general, values below 100 are recommended, unless • 200: message scrollback (|pager|)
there is a good reason to overshadow builtin elements. • 250: |cmdline-completion| popupmenu (wildoptions=pum)
The cursor is dimmed if an unfocused float above the
cursor exceeds the zindex of the current window by 50.
• _cmdline_offset: (EXPERIMENTAL) When provided, anchor the • _cmdline_offset: (EXPERIMENTAL) When provided, anchor the
|cmdline-completion| popupmenu to this window, with an |cmdline-completion| popupmenu to this window, with an
offset in screen cell width. offset in screen cell width.
+231 -120
View File
@@ -226,16 +226,17 @@ autocommands, this doesn't happen.
You can use the 'eventignore' option to ignore a number of events or all You can use the 'eventignore' option to ignore a number of events or all
events. events.
Events that provide |event-data| have a matching `vim.event.<name>.data` type *event-data-types*
defined in `runtime/lua/vim/_meta/events.lua`. You can use @cast to narrow Events that provide |event-data| have a corresponding `vim.event.<name>.data`
`ev.data` for type-checking and completion: >lua type defined in `runtime/lua/vim/_meta/events.lua`. If you have Lua LSP
enabled, you can annotate your handler to get type-checking and completion: >lua
vim.api.nvim_create_autocmd('LspAttach', { vim.api.nvim_create_autocmd('LspAttach', {
callback = function(ev) ---@param ev {data: vim.event.lspattach.data}
---@cast ev {data: vim.event.lspattach.data} callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id) local client = vim.lsp.get_client_by_id(ev.data.client_id)
end, end,
}) })
< <
*events* *{event}* *events* *{event}*
Nvim recognizes the following events. Names are case-insensitive. Nvim recognizes the following events. Names are case-insensitive.
@@ -248,6 +249,7 @@ BufAdd After adding a new buffer or existing unlisted
Before |BufEnter|. Before |BufEnter|.
NOTE: Current buffer "%" is not the target NOTE: Current buffer "%" is not the target
buffer "<afile>", "<abuf>". |<buffer=abuf>| buffer "<afile>", "<abuf>". |<buffer=abuf>|
*BufDelete* *BufDelete*
BufDelete Before deleting a buffer from the buffer list. BufDelete Before deleting a buffer from the buffer list.
The BufUnload may be called first (if the The BufUnload may be called first (if the
@@ -257,6 +259,7 @@ BufDelete Before deleting a buffer from the buffer list.
NOTE: Current buffer "%" is not the target NOTE: Current buffer "%" is not the target
buffer "<afile>", "<abuf>". |<buffer=abuf>| buffer "<afile>", "<abuf>". |<buffer=abuf>|
Do not change to another buffer. Do not change to another buffer.
*BufEnter* *BufEnter*
BufEnter After entering (visiting, switching-to) a new BufEnter After entering (visiting, switching-to) a new
or existing buffer. Useful for setting or existing buffer. Useful for setting
@@ -264,12 +267,15 @@ BufEnter After entering (visiting, switching-to) a new
does not trigger for existing buffers. does not trigger for existing buffers.
After |BufAdd|. After |BufAdd|.
After |BufReadPost|. After |BufReadPost|.
*BufFilePost* *BufFilePost*
BufFilePost After changing the name of the current buffer BufFilePost After changing the name of the current buffer
with the ":file" or ":saveas" command. with the ":file" or ":saveas" command.
*BufFilePre* *BufFilePre*
BufFilePre Before changing the name of the current buffer BufFilePre Before changing the name of the current buffer
with the ":file" or ":saveas" command. with the ":file" or ":saveas" command.
*BufHidden* *BufHidden*
BufHidden Before a buffer becomes hidden: when there are BufHidden Before a buffer becomes hidden: when there are
no longer windows that show the buffer, but no longer windows that show the buffer, but
@@ -278,15 +284,18 @@ BufHidden Before a buffer becomes hidden: when there are
Not used for ":qa" or ":q" when exiting Vim. Not used for ":qa" or ":q" when exiting Vim.
NOTE: Current buffer "%" is not the target NOTE: Current buffer "%" is not the target
buffer "<afile>", "<abuf>". |<buffer=abuf>| buffer "<afile>", "<abuf>". |<buffer=abuf>|
*BufLeave* *BufLeave*
BufLeave Before leaving to another buffer. Also when BufLeave Before leaving to another buffer. Also when
leaving or closing the current window and the leaving or closing the current window and the
new current window is not for the same buffer. new current window is not for the same buffer.
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. Special-case of |OptionSet|.
*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
@@ -296,10 +305,12 @@ BufNew After creating a new buffer (except during
NOTE: Current buffer "%" is not the target NOTE: Current buffer "%" is not the target
buffer "<afile>", "<abuf>". |<buffer=abuf>| buffer "<afile>", "<abuf>". |<buffer=abuf>|
See also |BufAdd|, |BufNewFile|. See also |BufAdd|, |BufNewFile|.
*BufNewFile* *BufNewFile*
BufNewFile When starting to edit a file that doesn't BufNewFile When starting to edit a file that doesn't
exist. Can be used to read in a skeleton exist. Can be used to read in a skeleton
file. file.
*BufRead* *BufReadPost* *BufRead* *BufReadPost*
BufRead or BufReadPost When starting to edit a new buffer, after BufRead or BufReadPost When starting to edit a new buffer, after
reading the file into the buffer, before reading the file into the buffer, before
@@ -314,13 +325,16 @@ BufRead or BufReadPost When starting to edit a new buffer, after
Not triggered: Not triggered:
- for the `:read file` command - for the `:read file` command
- when the file doesn't exist - when the file doesn't exist
*BufReadCmd* *BufReadCmd*
BufReadCmd Before starting to edit a new buffer. Should BufReadCmd Before starting to edit a new buffer. Should
read the file into the buffer. |Cmd-event| read the file into the buffer. |Cmd-event|
*BufReadPre* *E200* *E201* *BufReadPre* *E200* *E201*
BufReadPre When starting to edit a new buffer, before BufReadPre When starting to edit a new buffer, before
reading the file into the buffer. Not used reading the file into the buffer. Not used
if the file doesn't exist. if the file doesn't exist.
*BufUnload* *BufUnload*
BufUnload Before unloading a buffer, when the text in BufUnload Before unloading a buffer, when the text in
the buffer is going to be freed. the buffer is going to be freed.
@@ -334,6 +348,7 @@ BufUnload Before unloading a buffer, when the text in
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.
*BufWinEnter* *BufWinEnter*
BufWinEnter After a buffer is displayed in a window. This BufWinEnter After a buffer is displayed in a window. This
may be when the buffer is loaded (after may be when the buffer is loaded (after
@@ -345,6 +360,7 @@ BufWinEnter After a buffer is displayed in a window. This
with a file already open in a window. with a file already open in a window.
Triggered for ":split" with the name of the Triggered for ":split" with the name of the
current buffer, since it reloads that buffer. current buffer, since it reloads that buffer.
*BufWinLeave* *BufWinLeave*
BufWinLeave Before a buffer is removed from a window. BufWinLeave Before a buffer is removed from a window.
Not when it's still visible in another window. Not when it's still visible in another window.
@@ -354,6 +370,7 @@ BufWinLeave Before a buffer is removed from a window.
buffer "<afile>", "<abuf>". |<buffer=abuf>| buffer "<afile>", "<abuf>". |<buffer=abuf>|
Not triggered when exiting and v:dying is 2 or Not triggered when exiting and v:dying is 2 or
more. more.
*BufWipeout* *BufWipeout*
BufWipeout Before completely deleting a buffer. The BufWipeout Before completely deleting a buffer. The
BufUnload and BufDelete events may be called BufUnload and BufDelete events may be called
@@ -364,8 +381,10 @@ BufWipeout Before completely deleting a buffer. The
NOTE: Current buffer "%" is not the target NOTE: Current buffer "%" is not the target
buffer "<afile>", "<abuf>". |<buffer=abuf>| buffer "<afile>", "<abuf>". |<buffer=abuf>|
Do not change to another buffer. Do not change to another buffer.
*BufWrite* *BufWritePre* *BufWrite* *BufWritePre*
BufWrite or BufWritePre Before writing the whole buffer to a file. BufWrite or BufWritePre Before writing the whole buffer to a file.
*BufWriteCmd* *BufWriteCmd*
BufWriteCmd Before writing the whole buffer to a file. BufWriteCmd Before writing the whole buffer to a file.
Should do the writing of the file and reset Should do the writing of the file and reset
@@ -377,9 +396,11 @@ BufWriteCmd Before writing the whole buffer to a file.
states as 'modified', like |:write| does. Use states as 'modified', like |:write| does. Use
the |'[| and |']| marks for the range of lines. 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
(should undo the commands for BufWritePre). (should undo the commands for BufWritePre).
*ChanInfo* *ChanInfo*
ChanInfo State of channel changed, for instance the ChanInfo State of channel changed, for instance the
client of a RPC channel described itself. client of a RPC channel described itself.
@@ -387,30 +408,21 @@ ChanInfo State of channel changed, for instance the
autocommand defined without |autocmd-nested|. autocommand defined without |autocmd-nested|.
Sets these |v:event| keys: Sets these |v:event| keys:
info as from |nvim_get_chan_info()| info as from |nvim_get_chan_info()|
*ChanOpen* *ChanOpen*
ChanOpen Just after a channel was opened. ChanOpen Just after a channel was opened.
This is triggered even when inside an This is triggered even when inside an
autocommand defined without |autocmd-nested|. autocommand defined without |autocmd-nested|.
Sets these |v:event| keys: Sets these |v:event| keys:
info as from |nvim_get_chan_info()| info as from |nvim_get_chan_info()|
*CmdUndefined*
CmdUndefined When a user command is used but it isn't
defined. Useful for defining a command only
when it's used. The pattern is matched
against the command name. Both <amatch> and
<afile> expand to the command name.
This is triggered even when inside an
autocommand defined without |autocmd-nested|.
NOTE: Autocompletion won't work until the
command is defined. An alternative is to
always define the user command and have it
invoke an autoloaded function. See |autoload|.
*CmdlineChanged* *CmdlineChanged*
CmdlineChanged After EVERY change inside command line. Also CmdlineChanged After EVERY change inside command line. Also
triggered during mappings! Use |<Cmd>| instead triggered during mappings! Use |<Cmd>| instead
of ":" in mappings, to avoid that. of ":" in mappings, to avoid that.
<afile> expands to the |cmdline-char|. <afile> expands to the |cmdline-char|.
*CmdlineEnter* *CmdlineEnter*
CmdlineEnter After entering the command-line (including CmdlineEnter After entering the command-line (including
non-interactive use of ":" in a mapping: use non-interactive use of ":" in a mapping: use
@@ -420,6 +432,7 @@ CmdlineEnter After entering the command-line (including
Sets these |v:event| keys: Sets these |v:event| keys:
cmdlevel cmdlevel
cmdtype cmdtype
*CmdlineLeave* *CmdlineLeave*
CmdlineLeave Before leaving the command-line (including CmdlineLeave Before leaving the command-line (including
non-interactive use of ":" in a mapping: use non-interactive use of ":" in a mapping: use
@@ -434,6 +447,7 @@ 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*
CmdlineLeavePre Just before leaving the command line, and CmdlineLeavePre Just before leaving the command line, and
before |CmdlineLeave|. Useful for capturing before |CmdlineLeave|. Useful for capturing
@@ -445,6 +459,20 @@ CmdlineLeavePre Just before leaving the command line, and
abandoning the command line by typing CTRL-C abandoning the command line by typing CTRL-C
or <Esc>. <afile> is set to |cmdline-char|. or <Esc>. <afile> is set to |cmdline-char|.
Sets |v:char| as with |CmdlineLeave|. Sets |v:char| as with |CmdlineLeave|.
*CmdUndefined*
CmdUndefined When a user command is used but it isn't
defined. Useful for defining a command only
when it's used. The pattern is matched
against the command name. Both <amatch> and
<afile> expand to the command name.
This is triggered even when inside an
autocommand defined without |autocmd-nested|.
NOTE: Autocompletion won't work until the
command is defined. An alternative is to
always define the user command and have it
invoke an autoloaded function. See |autoload|.
*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
@@ -452,6 +480,7 @@ CmdwinEnter After entering the command-line window.
<afile> expands to a single character, <afile> expands to a single character,
indicating the type of command-line. indicating the type of command-line.
|cmdwin-char| |cmdwin-char|
*CmdwinLeave* *CmdwinLeave*
CmdwinLeave Before leaving the command-line window. CmdwinLeave Before leaving the command-line window.
Useful to clean up any global setting done Useful to clean up any global setting done
@@ -459,6 +488,7 @@ CmdwinLeave Before leaving the command-line window.
<afile> expands to a single character, <afile> expands to a single character,
indicating the type of command-line. indicating the type of command-line.
|cmdwin-char| |cmdwin-char|
*ColorScheme* *ColorScheme*
ColorScheme After loading a color scheme. |:colorscheme| ColorScheme After loading a color scheme. |:colorscheme|
Not triggered if the color scheme is not Not triggered if the color scheme is not
@@ -495,13 +525,6 @@ CompleteChanged *CompleteChanged*
The size and position of the popup are also The size and position of the popup are also
available by calling |pum_getpos()|. available by calling |pum_getpos()|.
*CompleteDonePre*
CompleteDonePre After Insert mode completion is done. Either
when something was completed or discarded.
|ins-completion|
|complete_info()| is valid during this event.
|v:completed_item| gives the completed item.
*CompleteDone* *CompleteDone*
CompleteDone After Insert mode completion is done. Either CompleteDone After Insert mode completion is done. Either
when something was completed or discarded. when something was completed or discarded.
@@ -526,6 +549,13 @@ CompleteDone After Insert mode completion is done. Either
- "discard": completion was - "discard": completion was
abandoned for other reason. abandoned for other reason.
*CompleteDonePre*
CompleteDonePre After Insert mode completion is done. Either
when something was completed or discarded.
|ins-completion|
|complete_info()| is valid during this event.
|v:completed_item| gives the completed item.
*CursorHold* *CursorHold*
CursorHold When there is no user input for 'updatetime' CursorHold When there is no user input for 'updatetime'
duration, in Normal-mode. Not triggered while duration, in Normal-mode. Not triggered while
@@ -561,20 +591,24 @@ CursorMoved After the cursor was moved in Normal or Visual
Careful: This is triggered very often, don't Careful: This is triggered very often, don't
do anything that the user does not expect or do anything that the user does not expect or
that is slow. that is slow.
*CursorMovedC* *CursorMovedC*
CursorMovedC After the cursor was moved in the command CursorMovedC After the cursor was moved in the command
line. Be careful not to mess up the command line. Be careful not to mess up the command
line, it may cause Vim to lock up. line, it may cause Vim to lock up.
<afile> expands to the |cmdline-char|. <afile> expands to the |cmdline-char|.
*CursorMovedI* *CursorMovedI*
CursorMovedI After the cursor was moved in Insert mode. CursorMovedI After the cursor was moved in Insert mode.
Not triggered when the popup menu is visible. Not triggered when the popup menu is visible.
Otherwise the same as CursorMoved. Otherwise the same as CursorMoved.
*DiffUpdated* *DiffUpdated*
DiffUpdated After diffs have been updated. Depending on DiffUpdated After diffs have been updated. Depending on
what kind of diff is being used (internal or what kind of diff is being used (internal or
external) this can be triggered on every external) this can be triggered on every
change or when doing |:diffupdate|. change or when doing |:diffupdate|.
*DirChanged* *DirChanged*
DirChanged After the |current-directory| was changed. DirChanged After the |current-directory| was changed.
The pattern can be: The pattern can be:
@@ -589,6 +623,7 @@ DirChanged After the |current-directory| was changed.
switching window (or tab) switching window (or tab)
<afile> is set to the new directory name. <afile> is set to the new directory name.
Non-recursive (event cannot trigger itself). Non-recursive (event cannot trigger itself).
*DirChangedPre* *DirChangedPre*
DirChangedPre When the |current-directory| is going to be DirChangedPre When the |current-directory| is going to be
changed, as with |DirChanged|. changed, as with |DirChanged|.
@@ -600,6 +635,7 @@ DirChangedPre When the |current-directory| is going to be
switching window (or tab) switching window (or tab)
<afile> is set to the new directory name. <afile> is set to the new directory name.
Non-recursive (event cannot trigger itself). Non-recursive (event cannot trigger itself).
*ExitPre* *ExitPre*
ExitPre When using `:quit`, `:wq` in a way it makes ExitPre When using `:quit`, `:wq` in a way it makes
Vim exit, or using `:qall`, just after Vim exit, or using `:qall`, just after
@@ -609,15 +645,19 @@ ExitPre When using `:quit`, `:wq` in a way it makes
isn't automatically saved, use |VimLeavePre| isn't automatically saved, use |VimLeavePre|
for really exiting. for really exiting.
See also |QuitPre|, |WinClosed|. See also |QuitPre|, |WinClosed|.
*FileAppendCmd* *FileAppendCmd*
FileAppendCmd Before appending to a file. Should do the FileAppendCmd Before appending to a file. Should do the
appending to the file. Use the '[ and '] appending to the file. Use the '[ and ']
marks for the range of lines. |Cmd-event| marks for the range of lines. |Cmd-event|
*FileAppendPost* *FileAppendPost*
FileAppendPost After appending to a file. FileAppendPost After appending to a file.
*FileAppendPre* *FileAppendPre*
FileAppendPre Before appending to a file. Use the '[ and '] FileAppendPre Before appending to a file. Use the '[ and ']
marks for the range of lines. marks for the range of lines.
*FileChangedRO* *FileChangedRO*
FileChangedRO Before making the first change to a read-only FileChangedRO Before making the first change to a read-only
file. Can be used to checkout the file from file. Can be used to checkout the file from
@@ -635,6 +675,7 @@ FileChangedRO Before making the first change to a read-only
*E881* *E881*
If the number of lines changes saving for undo If the number of lines changes saving for undo
may fail and the change will be aborted. may fail and the change will be aborted.
*FileChangedShell* *FileChangedShell*
FileChangedShell When Vim notices that the modification time of FileChangedShell When Vim notices that the modification time of
a file has changed since editing started. a file has changed since editing started.
@@ -657,19 +698,24 @@ FileChangedShell When Vim notices that the modification time of
*E246* *E811* *E246* *E811*
Cannot switch, jump to or delete buffers. Cannot switch, jump to or delete buffers.
Non-recursive (event cannot trigger itself). Non-recursive (event cannot trigger itself).
*FileChangedShellPost* *FileChangedShellPost*
FileChangedShellPost After handling a file that was changed outside FileChangedShellPost After handling a file that was changed outside
of Vim. Can be used to update the statusline. of Vim. Can be used to update the statusline.
*FileReadCmd* *FileReadCmd*
FileReadCmd Before reading a file with a ":read" command. FileReadCmd Before reading a file with a ":read" command.
Should do the reading of the file. |Cmd-event| Should do the reading of the file. |Cmd-event|
*FileReadPost* *FileReadPost*
FileReadPost After reading a file with a ":read" command. FileReadPost After reading a file with a ":read" command.
Note that Vim sets the '[ and '] marks to the Note that Vim sets the '[ and '] marks to the
first and last line of the read. This can be first and last line of the read. This can be
used to operate on the lines just read. used to operate on the lines just read.
*FileReadPre* *FileReadPre*
FileReadPre Before reading a file with a ":read" command. FileReadPre Before reading a file with a ":read" command.
*FileType* *FileType*
FileType When the 'filetype' option has been set. The FileType When the 'filetype' option has been set. The
pattern is matched against the filetype. pattern is matched against the filetype.
@@ -678,24 +724,29 @@ FileType When the 'filetype' option has been set. The
'filetype'. 'filetype'.
Cannot switch windows or buffers. Cannot switch windows or buffers.
See |filetypes|. See |filetypes|.
*FileWriteCmd* *FileWriteCmd*
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.
Vim checks the pattern against the name of Vim checks the pattern against the name of
the current buffer as with FilterReadPre. the current buffer as with FilterReadPre.
Not triggered when 'shelltemp' is off. Not triggered when 'shelltemp' is off.
*FilterReadPre* *E135* *FilterReadPre* *E135*
FilterReadPre Before reading a file from a filter command. FilterReadPre Before reading a file from a filter command.
Vim checks the pattern against the name of Vim checks the pattern against the name of
@@ -703,6 +754,7 @@ FilterReadPre Before reading a file from a filter command.
temporary file that is the output of the temporary file that is the output of the
filter command. filter command.
Not triggered when 'shelltemp' is off. Not triggered when 'shelltemp' is off.
*FilterWritePost* *FilterWritePost*
FilterWritePost After writing a file for a filter command or FilterWritePost After writing a file for a filter command or
making a diff with an external diff (see making a diff with an external diff (see
@@ -710,6 +762,7 @@ FilterWritePost After writing a file for a filter command or
Vim checks the pattern against the name of Vim checks the pattern against the name of
the current buffer as with FilterWritePre. the current buffer as with FilterWritePre.
Not triggered when 'shelltemp' is off. Not triggered when 'shelltemp' is off.
*FilterWritePre* *FilterWritePre*
FilterWritePre Before writing a file for a filter command or FilterWritePre Before writing a file for a filter command or
making a diff with an external diff. making a diff with an external diff.
@@ -718,11 +771,14 @@ FilterWritePre Before writing a file for a filter command or
temporary file that is the output of the temporary file that is the output of the
filter command. filter command.
Not triggered when 'shelltemp' is off. Not triggered when 'shelltemp' is off.
*FocusGained* *FocusGained*
FocusGained Nvim got focus. FocusGained Nvim got focus.
*FocusLost* *FocusLost*
FocusLost Nvim lost focus. Also (potentially) when FocusLost Nvim lost focus. Also (potentially) when
a GUI dialog pops up. a GUI dialog pops up.
*FuncUndefined* *FuncUndefined*
FuncUndefined When a user function is used but it isn't FuncUndefined When a user function is used but it isn't
defined. Useful for defining a function only defined. Useful for defining a function only
@@ -734,22 +790,14 @@ FuncUndefined When a user function is used but it isn't
NOTE: When writing Vim scripts a better NOTE: When writing Vim scripts a better
alternative is to use an autoloaded function. alternative is to use an autoloaded function.
See |autoload-functions|. See |autoload-functions|.
*UIEnter*
UIEnter After a UI connects via |nvim_ui_attach()|, or
after builtin TUI is started, after |VimEnter|.
Sets these |v:event| keys:
chan: |channel-id| of the UI
*UILeave*
UILeave After a UI disconnects from Nvim, or after
builtin TUI is stopped, after |VimLeave|.
Sets these |v:event| keys:
chan: |channel-id| of the UI
*InsertChange* *InsertChange*
InsertChange When typing <Insert> while in Insert or InsertChange When typing <Insert> while in Insert or
Replace mode. The |v:insertmode| variable Replace mode. The |v:insertmode| variable
indicates the new mode. indicates the new mode.
Be careful not to move the cursor or do Be careful not to move the cursor or do
anything else that the user does not expect. anything else that the user does not expect.
*InsertCharPre* *InsertCharPre*
InsertCharPre When a character is typed in Insert mode, InsertCharPre When a character is typed in Insert mode,
before inserting the char. before inserting the char.
@@ -760,6 +808,7 @@ InsertCharPre When a character is typed in Insert mode,
inserted literally. inserted literally.
Cannot change the text. |textlock| Cannot change the text. |textlock|
*InsertEnter* *InsertEnter*
InsertEnter Just before starting Insert mode. Also for InsertEnter Just before starting Insert mode. Also for
Replace mode and Virtual Replace mode. The Replace mode and Virtual Replace mode. The
@@ -769,20 +818,24 @@ InsertEnter Just before starting Insert mode. Also for
The cursor is restored afterwards. If you do The cursor is restored afterwards. If you do
not want that set |v:char| to a non-empty not want that set |v:char| to a non-empty
string. string.
*InsertLeavePre* *InsertLeavePre*
InsertLeavePre Just before leaving Insert mode. Also when InsertLeavePre Just before leaving Insert mode. Also when
using CTRL-O |i_CTRL-O|. Be careful not to using CTRL-O |i_CTRL-O|. Be careful not to
change mode or use `:normal`, it will likely change mode or use `:normal`, it will likely
cause trouble. cause trouble.
*InsertLeave* *InsertLeave*
InsertLeave Just after leaving Insert mode. Also when InsertLeave Just after leaving Insert mode. Also when
using CTRL-O |i_CTRL-O|. But not for |i_CTRL-C|. using CTRL-O |i_CTRL-O|. But not for |i_CTRL-C|.
LspAttach See |LspAttach| LspAttach See |LspAttach|
LspDetach See |LspDetach| LspDetach See |LspDetach|
LspNotify See |LspNotify| LspNotify See |LspNotify|
LspProgress See |LspProgress| LspProgress See |LspProgress|
LspRequest See |LspRequest| LspRequest See |LspRequest|
LspTokenUpdate See |LspTokenUpdate| LspTokenUpdate See |LspTokenUpdate|
*MarkSet* *MarkSet*
MarkSet After a |mark| is set by |m|, |:mark|, and MarkSet After a |mark| is set by |m|, |:mark|, and
|nvim_buf_set_mark()|. Supports `[a-zA-Z]` |nvim_buf_set_mark()|. Supports `[a-zA-Z]`
@@ -795,7 +848,6 @@ MarkSet After a |mark| is set by |m|, |:mark|, and
- name: Mark name (e.g. "a") - name: Mark name (e.g. "a")
- line: Mark line. - line: Mark line.
- col: Mark column. - col: Mark column.
See `vim.event.markset.data`.
*MenuPopup* *MenuPopup*
MenuPopup Just before showing the popup menu (under the MenuPopup Just before showing the popup menu (under the
@@ -810,6 +862,7 @@ MenuPopup Just before showing the popup menu (under the
i Insert i Insert
c Command line c Command line
tl Terminal tl Terminal
*ModeChanged* *ModeChanged*
ModeChanged After changing the mode. The pattern is ModeChanged After changing the mode. The pattern is
matched against `'old_mode:new_mode'`, for matched against `'old_mode:new_mode'`, for
@@ -826,37 +879,12 @@ ModeChanged After changing the mode. The pattern is
This will be triggered on every minor mode This will be triggered on every minor mode
change. change.
Usage example to use relative line numbers Usage example to use relative line numbers
when entering visual mode: > when entering visual mode: >vim
: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 *OptionSet*
`nvim_echo`. The pattern is matched against
`source` of the message. The |event-data| contains:
id: id of the message
text: text of the message
title: title of the progress message
source: source of the progress message
status: status of the progress message
percent: how much progress has been
made for this progress item
data: arbitaray data sent with
progress message
See `vim.event.progress.data`.
Usage example:
>lua
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', source='search'})
vim.api.nvim_echo({{'searching'}}, true, {id = id, kind='progress', status='running', percent=50, title='term', source='search'})
vim.api.nvim_echo({{'done'}}, true, {id = id, kind='progress', status='success', percent=100, title='term', source='search'})
< *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
against the long option name. |<amatch>| against the long option name. |<amatch>|
@@ -905,6 +933,36 @@ OptionSet After setting an option (except during
Not triggered on startup. Not triggered on startup.
PackChangedPre See |PackChangedPre|
PackChanged See |PackChanged|
Progress *Progress*
After a |progress-message| is created or updated via
`nvim_echo`. The pattern is matched against
`source` of the message.
The |event-data| has these keys (type: `vim.event.progress.data`):
- id: id of the message
- text: text of the message
- title: title of the progress message
- source: source of the progress message
- status: status of the progress message
- percent: how much progress has been made
- data: arbitrary data sent with the message
Usage example:
>lua
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', source='search'})
vim.api.nvim_echo({{'searching'}}, true, {id = id, kind='progress', status='running', percent=50, title='term', source='search'})
vim.api.nvim_echo({{'done'}}, true, {id = id, kind='progress', status='success', percent=100, title='term', source='search'})
<
*QuickFixCmdPre* *QuickFixCmdPre*
QuickFixCmdPre Before a quickfix command is run (|:make|, QuickFixCmdPre Before a quickfix command is run (|:make|,
|:lmake|, |:grep|, |:lgrep|, |:grepadd|, |:lmake|, |:grep|, |:lgrep|, |:grepadd|,
@@ -922,6 +980,7 @@ QuickFixCmdPre Before a quickfix command is run (|:make|,
'makeprg' and 'grepprg' variables. 'makeprg' and 'grepprg' variables.
If this command causes an error, the quickfix If this command causes an error, the quickfix
command is not executed. command is not executed.
*QuickFixCmdPost* *QuickFixCmdPost*
QuickFixCmdPost Like QuickFixCmdPre, but after a quickfix QuickFixCmdPost Like QuickFixCmdPre, but after a quickfix
command is run, before jumping to the first command is run, before jumping to the first
@@ -929,6 +988,7 @@ QuickFixCmdPost Like QuickFixCmdPre, but after a quickfix
it is run after the error file is read and it is run after the error file is read and
before moving to the first error. before moving to the first error.
See |QuickFixCmdPost-example|. See |QuickFixCmdPost-example|.
*QuitPre* *QuitPre*
QuitPre When using `:quit`, `:wq` or `:qall`, before QuitPre When using `:quit`, `:wq` or `:qall`, before
deciding whether it closes the current window deciding whether it closes the current window
@@ -937,25 +997,13 @@ QuitPre When using `:quit`, `:wq` or `:qall`, before
close any non-essential window if the current close any non-essential window if the current
window is the last ordinary window. window is the last ordinary window.
See also |ExitPre|, |WinClosed|. See also |ExitPre|, |WinClosed|.
*RemoteReply*
RemoteReply When a reply from a Vim that functions as
server was received server2client(). The
pattern is matched against the {serverid}.
<amatch> is equal to the {serverid} from which
the reply was sent, and <afile> is the actual
reply string.
Note that even if an autocommand is defined,
the reply should be read with remote_read()
to consume it.
*SearchWrapped*
SearchWrapped After making a search with |n| or |N| if the
search wraps around the document back to
the start/finish respectively.
*RecordingEnter* *RecordingEnter*
RecordingEnter When a macro starts recording. RecordingEnter When a macro starts recording.
The pattern is the current file name, and The pattern is the current file name, and
|reg_recording()| is the current register that |reg_recording()| is the current register that
is used. is used.
*RecordingLeave* *RecordingLeave*
RecordingLeave When a macro stops recording. RecordingLeave When a macro stops recording.
The pattern is the current file name, and The pattern is the current file name, and
@@ -966,6 +1014,18 @@ RecordingLeave When a macro stops recording.
Sets these |v:event| keys: Sets these |v:event| keys:
regcontents regcontents
regname regname
*RemoteReply*
RemoteReply When a reply from a Vim that functions as
server was received server2client(). The
pattern is matched against the {serverid}.
<amatch> is equal to the {serverid} from which
the reply was sent, and <afile> is the actual
reply string.
Note that even if an autocommand is defined,
the reply should be read with remote_read()
to consume it.
*SafeState* *SafeState*
SafeState When nothing is pending, going to wait for the SafeState When nothing is pending, going to wait for the
user to type a character. user to type a character.
@@ -987,21 +1047,35 @@ SafeState When nothing is pending, going to wait for the
check more with `state()`, e.g. whether the check more with `state()`, e.g. whether the
screen was scrolled for messages. screen was scrolled for messages.
*SearchWrapped*
SearchWrapped After making a search with |n| or |N| if the
search wraps around the document back to
the start/finish respectively.
*SessionLoadPre* *SessionLoadPre*
SessionLoadPre Before loading the session file created using SessionLoadPre Before loading the session file created using
the |:mksession| command. the |:mksession| command.
*SessionLoadPost* *SessionLoadPost*
SessionLoadPost After loading the session file created using SessionLoadPost After loading the session file created using
the |:mksession| command. the |:mksession| command.
*SessionWritePost* *SessionWritePost*
SessionWritePost After writing a session file by calling SessionWritePost After writing a session file by calling
the |:mksession| command. the |:mksession| command.
*ShellCmdPost* *ShellCmdPost*
ShellCmdPost After executing a shell command with |:!cmd|, ShellCmdPost After executing a shell command with |:!cmd|,
|:make| and |:grep|. Can be used to check for |:make| and |:grep|. Can be used to check for
any changed files. any changed files.
For non-blocking shell commands, see For non-blocking shell commands, see
|job-control|. |job-control|.
*ShellFilterPost*
ShellFilterPost After executing a shell command with
":{range}!cmd", ":w !cmd" or ":r !cmd".
Can be used to check for any changed files.
*Signal* *Signal*
Signal After Nvim receives a signal. The pattern is Signal After Nvim receives a signal. The pattern is
matched against the signal name. Only matched against the signal name. Only
@@ -1010,36 +1084,39 @@ Signal After Nvim receives a signal. The pattern is
autocommand defined without |autocmd-nested|. autocommand defined without |autocmd-nested|.
Example: >vim Example: >vim
autocmd Signal SIGUSR1 call some#func() autocmd Signal SIGUSR1 call some#func()
< *ShellFilterPost*
ShellFilterPost After executing a shell command with < *SourceCmd*
":{range}!cmd", ":w !cmd" or ":r !cmd". SourceCmd When sourcing a Vimscript/Lua file. |:source|
Can be used to check for any changed files. <afile> is the name of the file being sourced.
The autocommand must source that file.
|Cmd-event|
*SourcePre* *SourcePre*
SourcePre Before sourcing a Vimscript/Lua file. |:source| SourcePre Before sourcing a Vimscript/Lua file. |:source|
<afile> is the name of the file being sourced. <afile> is the name of the file being sourced.
*SourcePost* *SourcePost*
SourcePost After sourcing a Vimscript/Lua file. |:source| SourcePost After sourcing a Vimscript/Lua file. |:source|
<afile> is the name of the file being sourced. <afile> is the name of the file being sourced.
Not triggered when sourcing was interrupted. Not triggered when sourcing was interrupted.
Also triggered after a SourceCmd autocommand Also triggered after a SourceCmd autocommand
was triggered. was triggered.
*SourceCmd*
SourceCmd When sourcing a Vimscript/Lua file. |:source|
<afile> is the name of the file being sourced.
The autocommand must source that file.
|Cmd-event|
*SpellFileMissing* *SpellFileMissing*
SpellFileMissing When trying to load a spell checking file and SpellFileMissing When trying to load a spell checking file and
it can't be found. The pattern is matched it can't be found. The pattern is matched
against the language. <amatch> is the against the language. <amatch> is the
language, 'encoding' also matters. See language, 'encoding' also matters. See
|spell-SpellFileMissing|. |spell-SpellFileMissing|.
*StdinReadPost* *StdinReadPost*
StdinReadPost During startup, after reading from stdin into StdinReadPost During startup, after reading from stdin into
the buffer, before executing modelines. |--| the buffer, before executing modelines. |--|
*StdinReadPre* *StdinReadPre*
StdinReadPre During startup, before reading from stdin into StdinReadPre During startup, before reading from stdin into
the buffer. |--| the buffer. |--|
*SwapExists* *SwapExists*
SwapExists Detected an existing swap file when starting SwapExists Detected an existing swap file when starting
to edit a file. Only when it is possible to to edit a file. Only when it is possible to
@@ -1063,6 +1140,7 @@ SwapExists Detected an existing swap file when starting
*E812* *E812*
Cannot change to another buffer, change Cannot change to another buffer, change
the buffer name or change directory. the buffer name or change directory.
*Syntax* *Syntax*
Syntax When the 'syntax' option has been set. The Syntax When the 'syntax' option has been set. The
pattern is matched against the syntax name. pattern is matched against the syntax name.
@@ -1070,68 +1148,75 @@ Syntax When the 'syntax' option has been set. The
this option was set. <amatch> expands to the this option was set. <amatch> expands to the
new value of 'syntax'. new value of 'syntax'.
See |:syn-on|. See |:syn-on|.
*TabClosed* *TabClosed*
TabClosed After closing a tab page. <afile> expands to TabClosed After closing a tab page. <afile> expands to
the tab page number. the tab page number.
*TabClosedPre* *TabClosedPre*
TabClosedPre Before closing a tab page. The window layout TabClosedPre Before closing a tab page. The window layout
is locked, thus opening and closing of windows is locked, thus opening and closing of windows
is prohibited. is prohibited.
*TabEnter* *TabEnter*
TabEnter Just after entering a tab page. |tab-page| TabEnter Just after entering a tab page. |tab-page|
After WinEnter. After WinEnter.
Before BufEnter. Before BufEnter.
*TabLeave* *TabLeave*
TabLeave Just before leaving a tab page. |tab-page| TabLeave Just before leaving a tab page. |tab-page|
After WinLeave. After WinLeave.
*TabNew* *TabNew*
TabNew When creating a new tab page. |tab-page| TabNew When creating a new tab page. |tab-page|
After WinEnter. After WinEnter.
Before TabEnter. Before TabEnter.
*TabNewEntered* *TabNewEntered*
TabNewEntered After entering a new tab page. |tab-page| TabNewEntered After entering a new tab page. |tab-page|
After BufEnter. After BufEnter.
*TermClose*
TermClose When a |terminal| job ends.
Sets these |v:event| keys:
status job exit status, or -1 if the
terminal buffer is deleted
*TermEnter*
TermEnter After entering |Terminal-mode|.
After TermOpen.
*TermLeave*
TermLeave After leaving |Terminal-mode|.
After TermClose.
*TermOpen* *TermOpen*
TermOpen When a |terminal| job is starting. Can be TermOpen When a |terminal| job is starting. Can be
used to configure the terminal buffer. To get used to configure the terminal buffer. To get
the terminal process details: >lua the terminal process details: >lua
vim.print(vim.api.nvim_get_chan_info(vim.bo.channel)) vim.print(vim.api.nvim_get_chan_info(vim.bo.channel))
< <
*TermEnter*
TermEnter After entering |Terminal-mode|.
After TermOpen.
*TermLeave*
TermLeave After leaving |Terminal-mode|.
After TermClose.
*TermClose*
TermClose When a |terminal| job ends.
Sets these |v:event| keys:
status job exit status, or -1 if the
terminal buffer is deleted
*TermRequest* *TermRequest*
TermRequest When a |:terminal| child process emits an OSC, TermRequest When a |:terminal| child process emits an OSC,
DCS, or APC sequence. Sets |v:termrequest|. The DCS, or APC sequence. Sets |v:termrequest|.
|event-data| is a table with the following
fields:
The |event-data| has these keys (type: `vim.event.termrequest.data`):
- sequence: the received sequence - sequence: the received sequence
- terminator: the received sequence terminator (i.e. BEL or ST) - terminator: the received sequence terminator (i.e. BEL or ST)
- cursor: (1,0)-indexed, buffer-relative - cursor: (1,0)-indexed, buffer-relative
position of the cursor when the sequence was position of the cursor when the sequence was
received (line number may be <= 0 if the received (line number may be <= 0 if the
position is no longer in the buffer) position is no longer in the buffer)
See `vim.event.termrequest.data`.
This is triggered even when inside an This is triggered even when inside an
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 a DA1, OSC, DCS, or APC response from
the host terminal. Sets |v:termresponse|. The the host terminal. Sets |v:termresponse|.
|event-data| is a table with the following fields:
The |event-data| has these keys (type: `vim.event.termresponse.data`):
- sequence: the received sequence - sequence: the received sequence
See `vim.event.termresponse.data`.
This is triggered even when inside an This is triggered even when inside an
autocommand defined without |autocmd-nested|. autocommand defined without |autocmd-nested|.
@@ -1165,20 +1250,24 @@ TextChanged After a change was made to the text in the
Careful: This is triggered very often, don't Careful: This is triggered very often, don't
do anything that the user does not expect or do anything that the user does not expect or
that is slow. that is slow.
*TextChangedI* *TextChangedI*
TextChangedI After a change was made to the text in the TextChangedI After a change was made to the text in the
current buffer in Insert mode. current buffer in Insert mode.
Not triggered when the popup menu is visible. Not triggered when the popup menu is visible.
Otherwise the same as TextChanged. Otherwise the same as TextChanged.
*TextChangedP* *TextChangedP*
TextChangedP After a change was made to the text in the TextChangedP After a change was made to the text in the
current buffer in Insert mode, only when the current buffer in Insert mode, only when the
popup menu is visible. Otherwise the same as popup menu is visible. Otherwise the same as
TextChanged. TextChanged.
*TextChangedT* *TextChangedT*
TextChangedT After a change was made to the text in the TextChangedT After a change was made to the text in the
current buffer in |Terminal-mode|. Otherwise current buffer in |Terminal-mode|. Otherwise
the same as TextChanged. the same as TextChanged.
*TextYankPost* *TextYankPost*
TextYankPost Just after a |yank| or |deleting| command, but not TextYankPost Just after a |yank| or |deleting| command, but not
if the black hole register |quote_| is used nor if the black hole register |quote_| is used nor
@@ -1196,15 +1285,30 @@ TextYankPost Just after a |yank| or |deleting| command, but not
Non-recursive (event cannot trigger itself). Non-recursive (event cannot trigger itself).
Cannot change the text. |textlock| Cannot change the text. |textlock|
*UIEnter*
UIEnter After a UI connects via |nvim_ui_attach()|, or
after builtin TUI is started, after |VimEnter|.
Sets these |v:event| keys:
chan: |channel-id| of the UI
*UILeave*
UILeave After a UI disconnects from Nvim, or after
builtin TUI is stopped, after |VimLeave|.
Sets these |v:event| keys:
chan: |channel-id| of the UI
*User* *User*
User Not executed automatically. Use |:doautocmd| User Not executed automatically. Use |:doautocmd|
to trigger this, typically for "custom events" to trigger this, typically for "custom events"
in a plugin. Example: > in a plugin. Example: >
:autocmd User MyPlugin echom 'got MyPlugin event' :autocmd User MyPlugin echom 'got MyPlugin event'
:doautocmd User MyPlugin :doautocmd User MyPlugin
< *UserGettingBored* < *UserGettingBored*
UserGettingBored When the user presses the same key 42 times. UserGettingBored When the user presses the same key 42 times.
Just kidding! :-) Just kidding! :-)
*VimEnter* *VimEnter*
VimEnter After doing all the startup stuff, including VimEnter After doing all the startup stuff, including
loading vimrc files, executing the "-c cmd" loading vimrc files, executing the "-c cmd"
@@ -1218,6 +1322,7 @@ VimEnter After doing all the startup stuff, including
else else
au VimEnter * call s:init() au VimEnter * call s:init()
endif endif
< *VimLeave* < *VimLeave*
VimLeave Before exiting Vim, just after writing the VimLeave Before exiting Vim, just after writing the
.shada file. Executed only once, like .shada file. Executed only once, like
@@ -1225,6 +1330,7 @@ VimLeave Before exiting Vim, just after writing the
Use |v:dying| to detect an abnormal exit. Use |v:dying| to detect an abnormal exit.
Use |v:exiting| to get the exit code. Use |v:exiting| to get the exit code.
Not triggered if |v:dying| is 2 or more. Not triggered if |v:dying| is 2 or more.
*VimLeavePre* *VimLeavePre*
VimLeavePre Before exiting Vim, just before writing the VimLeavePre Before exiting Vim, just before writing the
|shada| file. Executed only once, if the |shada| file. Executed only once, if the
@@ -1234,14 +1340,18 @@ VimLeavePre Before exiting Vim, just before writing the
< Use |v:dying| to detect an abnormal exit. < Use |v:dying| to detect an abnormal exit.
Use |v:exiting| to get the exit code. Use |v:exiting| to get the exit code.
Not triggered if |v:dying| is 2 or more. Not triggered if |v:dying| is 2 or more.
*VimResized* *VimResized*
VimResized After the Vim window was resized, thus 'lines' VimResized After the Vim window was resized, thus 'lines'
and/or 'columns' changed. Not when starting and/or 'columns' changed. Not when starting
up though. up though.
*VimResume* *VimResume*
VimResume After Nvim resumes from |suspend| state. VimResume After Nvim resumes from |suspend| state.
*VimSuspend* *VimSuspend*
VimSuspend Before Nvim enters |suspend| state. VimSuspend Before Nvim enters |suspend| state.
*WinClosed* *WinClosed*
WinClosed When closing a window, just before it is WinClosed When closing a window, just before it is
removed from the window layout. The pattern removed from the window layout. The pattern
@@ -1250,6 +1360,7 @@ WinClosed When closing a window, just before it is
After WinLeave. After WinLeave.
Non-recursive (event cannot trigger itself). Non-recursive (event cannot trigger itself).
See also |ExitPre|, |QuitPre|. See also |ExitPre|, |QuitPre|.
*WinEnter* *WinEnter*
WinEnter After entering another window. Not done for WinEnter After entering another window. Not done for
the first window, when Vim has just started. the first window, when Vim has just started.
@@ -1268,6 +1379,7 @@ WinLeave Before leaving a window. If the window to be
WinLeave autocommands (but not for ":new"). WinLeave autocommands (but not for ":new").
Not used for ":qa" or ":q" when exiting Vim. Not used for ":qa" or ":q" when exiting Vim.
Before WinClosed. Before WinClosed.
*WinNewPre* *WinNewPre*
WinNewPre Before creating a new window. Triggered WinNewPre Before creating a new window. Triggered
before commands that modify window layout by before commands that modify window layout by
@@ -1287,6 +1399,17 @@ WinNew When a new window was created. Not done for
the first window, when Vim has just started. the first window, when Vim has just started.
Before WinEnter. Before WinEnter.
*WinResized*
WinResized After a window in the current tab page changed
width or height.
See |win-scrolled-resized|.
|v:event| is set with information about size
changes. |WinResized-event|
Same behavior as |WinScrolled| for the
pattern, triggering and recursiveness.
*WinScrolled* *WinScrolled*
WinScrolled After any window in the current tab page WinScrolled After any window in the current tab page
scrolled the text (horizontally or vertically) scrolled the text (horizontally or vertically)
@@ -1320,18 +1443,6 @@ WinScrolled After any window in the current tab page
window to scroll or change size, then another window to scroll or change size, then another
WinScrolled event will be triggered later. WinScrolled event will be triggered later.
*WinResized*
WinResized After a window in the current tab page changed
width or height.
See |win-scrolled-resized|.
|v:event| is set with information about size
changes. |WinResized-event|
Same behavior as |WinScrolled| for the
pattern, triggering and recursiveness.
============================================================================== ==============================================================================
6. Patterns *autocmd-pattern* *{aupat}* 6. Patterns *autocmd-pattern* *{aupat}*
+5 -2
View File
@@ -306,10 +306,13 @@ To choose a new "EXX" error code (e.g. |E5555|), just print a message with
a new EXX number: > a new EXX number: >
emsg(_("E996: Invalid thing")); emsg(_("E996: Invalid thing"));
< <
You can confirm that the new error code isn't used by running: > To see existing error codes: >
:new | put =filter(getcompletion('h E', 'cmdline'), 'v:val =~# ''E\d\d''')
The `linterrcodes` build target checks that all "EXX" codes are unique and
have help tags. It runs in CI, but you can also run it locally: >
make linterrcodes make linterrcodes
< <
The `linterrcodes.lua` check requires the new error code to have a help tag.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Stdlib design *dev-lua* Stdlib design *dev-lua*
+15
View File
@@ -409,6 +409,11 @@ If both, the global `plugin_exec` and the `<filetype>_exec` specific variable
are set, the filetype specific variable should have precedent. are set, the filetype specific variable should have precedent.
ADA
Documentation for this plugin is here: |ft_ada.txt|.
ASCIIDOC *ft-asciidoc-plugin* ASCIIDOC *ft-asciidoc-plugin*
To enable |folding| use this: > To enable |folding| use this: >
@@ -905,6 +910,11 @@ To disable this behavior, set the following variable in your vimrc: >
let g:python_recommended_style = 0 let g:python_recommended_style = 0
POWERSHELL
Documentation for this plugin is here: |ft_ps1.txt|.
QUERY *ft-query-plugin* QUERY *ft-query-plugin*
@@ -967,6 +977,11 @@ and for LaTeX code. If you prefer that 'formatexpr' is not set, add to your
let rnw_dynamic_comments = 0 let rnw_dynamic_comments = 0
RAKU
Documentation for this plugin is here: |ft_raku.txt|.
RPM SPEC *ft-spec-plugin* RPM SPEC *ft-spec-plugin*
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
+5 -10
View File
@@ -80,19 +80,14 @@ API (extensibility/scripting/plugins)
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Programming language support Programming language support
- |lsp| Language Server Protocol (LSP)
- |diagnostic-api| Diagnostic framework - |diagnostic-api| Diagnostic framework
- |treesitter| Incremental syntax parsing
- |indent.txt| automatic indenting for C and other languages
- |syntax| syntax highlighting
- |filetype| Settings for specific types of files - |filetype| Settings for specific types of files
- |indent.txt| automatic indenting for C and other languages
- |lsp| Language Server Protocol (LSP)
- |quickfix| Commands for a quick edit-compile-fix cycle - |quickfix| Commands for a quick edit-compile-fix cycle
- |ft_ada.txt| Ada filetype plugin - |syntax| syntax highlighting
- |ft_hare.txt| Filetype plugin for Hare - |treesitter| Incremental syntax parsing
- |ft_ps1.txt| PowerShell filetype plugin - |vim.pack| Plugin manager
- |ft_raku.txt| Raku filetype plugin
- |ft_rust.txt| Rust filetype plugin
- |ft_sql.txt| SQL filetype plugin
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
UI UI
+1 -1
View File
@@ -1336,7 +1336,7 @@ The same, but now pretending searching for matches is slow: >
INSERT COMPLETION POPUP MENU *ins-completion-menu* INSERT COMPLETION POPUP MENU *ins-completion-menu*
*popupmenu-completion* *popupmenu-completion*
Vim can display the matches in a simplistic popup menu. Vim can display the matches in a popup menu.
The menu is used when: The menu is used when:
- The 'completeopt' option contains "menu" or "menuone". - The 'completeopt' option contains "menu" or "menuone".
+27 -17
View File
@@ -689,8 +689,8 @@ EVENTS *lsp-events*
LspAttach *LspAttach* LspAttach *LspAttach*
After an LSP client performs "initialize" and attaches to a buffer. The After an LSP client performs "initialize" and attaches to a buffer. The
|autocmd-pattern| is the buffer name. The client ID is passed in the |autocmd-pattern| is the buffer name. The |event-data| (type:
Lua handler |event-data| argument. See `vim.event.lspattach.data`. `vim.event.lspattach.data`) has the client ID.
Example: >lua Example: >lua
vim.api.nvim_create_autocmd('LspAttach', { vim.api.nvim_create_autocmd('LspAttach', {
@@ -722,8 +722,8 @@ LspAttach *LspAttach*
LspDetach *LspDetach* LspDetach *LspDetach*
Just before an LSP client detaches from a buffer. The |autocmd-pattern| is Just before an LSP client detaches from a buffer. The |autocmd-pattern| is
the buffer name. The client ID is passed in the Lua handler |event-data| the buffer name. The |event-data| (type: `vim.event.lspdetach.data`) has
argument. See `vim.event.lspdetach.data`. the client ID.
Example: >lua Example: >lua
vim.api.nvim_create_autocmd('LspDetach', { vim.api.nvim_create_autocmd('LspDetach', {
@@ -746,8 +746,8 @@ LspNotify *LspNotify*
This event is triggered after each successful notification sent to an This event is triggered after each successful notification sent to an
LSP server. LSP server.
The client_id, LSP method, and parameters are sent in the Lua handler The |event-data| (type: `vim.event.lspnotify.data`) has the client_id, LSP
|event-data| table argument. See `vim.event.lspnotify.data`. method, and parameters.
Example: >lua Example: >lua
vim.api.nvim_create_autocmd('LspNotify', { vim.api.nvim_create_autocmd('LspNotify', {
@@ -773,9 +773,9 @@ LspProgress *LspProgress*
If the server sends a "work done progress", the `pattern` is set to `kind` If the server sends a "work done progress", the `pattern` is set to `kind`
(one of `begin`, `report` or `end`). (one of `begin`, `report` or `end`).
The Lua handler |event-data| argument has `client_id` and `params` The |event-data| (type: `vim.event.lspprogress.data`) has `client_id` and
properties, where `params` is the request params sent by the server (see `params` properties, where `params` is the request params sent by the
`lsp.ProgressParams`). See `vim.event.lspprogress.data`. server (see `lsp.ProgressParams`).
Examples: Examples:
@@ -810,11 +810,10 @@ LspRequest *LspRequest*
is requested using `client.cancel_request(request_id)`, then this event is requested using `client.cancel_request(request_id)`, then this event
will trigger with {type} == `cancel`. will trigger with {type} == `cancel`.
The Lua handler |event-data| argument has the client ID, request ID, and The |event-data| (type: `vim.event.lsprequest.data`) has the client ID,
request (described at |vim.lsp.Client|, {requests} field). If the request request ID, and request (described at |vim.lsp.Client|, {requests} field).
type is `complete`, the request will be deleted from the client's pending If the request type is `complete`, the request will be deleted from the
requests table after processing the event handlers. client's pending requests table after processing the event handlers.
See `vim.event.lsprequest.data`.
Example: >lua Example: >lua
vim.api.nvim_create_autocmd('LspRequest', { vim.api.nvim_create_autocmd('LspRequest', {
@@ -841,9 +840,9 @@ LspRequest *LspRequest*
LspTokenUpdate *LspTokenUpdate* LspTokenUpdate *LspTokenUpdate*
When a visible semantic token is sent or updated by the LSP server, or When a visible semantic token is sent or updated by the LSP server, or
when an existing token becomes visible for the first time. The when an existing token becomes visible for the first time. The
|autocmd-pattern| is the buffer name. The Lua handler |event-data| |autocmd-pattern| is the buffer name. The |event-data| (type:
argument has the client ID and token (see `vim.event.lsptokenupdate.data`) has the client ID and token (see
|vim.lsp.semantic_tokens.get_at_pos()|). See `vim.event.lsptokenupdate.data`. |vim.lsp.semantic_tokens.get_at_pos()|).
Example: >lua Example: >lua
vim.api.nvim_create_autocmd('LspTokenUpdate', { vim.api.nvim_create_autocmd('LspTokenUpdate', {
@@ -1833,6 +1832,17 @@ Lua module: vim.lsp.client *lsp-client*
Function receives a `dispatchers` table and the Function receives a `dispatchers` table and the
resolved `config`, and must return an object in resolved `config`, and must return an object in
the form of |vim.lsp.rpc.Client|. the form of |vim.lsp.rpc.Client|.
Example (list): >lua
cmd = { 'flow', 'lsp' }
<
Example (function): >lua
cmd = function(dispatchers, config)
local cmd = vim.fn.executable('flow') == 1 and { 'flow', 'lsp' } or { 'npx', '--no-install', 'flow', 'lsp' }
return vim.lsp.rpc.start(cmd, dispatchers)
end
<
• See |vim.lsp.rpc.request()| • See |vim.lsp.rpc.request()|
|vim.lsp.rpc.notify()| |vim.lsp.rpc.notify()|
• For TCP there is a builtin RPC client • For TCP there is a builtin RPC client
+25 -25
View File
@@ -1164,9 +1164,9 @@ Option:remove({value}) *vim.opt:remove()*
• {value} (`string`) Value to remove • {value} (`string`) Value to remove
vim.bo[{bufnr}] *vim.bo* vim.bo[{bufnr}] *vim.bo*
Get or set buffer-scoped |options| for the buffer with number {bufnr}. Gets or sets buffer-scoped |options| on buffer {bufnr} (or "current
Like `:setlocal`. If {bufnr} is omitted then the current buffer is used. buffer" if 0 or omitted). Like `:setlocal`. Invalid {bufnr} or key is an
Invalid {bufnr} or key is an error. error.
Example: >lua Example: >lua
local bufnr = vim.api.nvim_get_current_buf() local bufnr = vim.api.nvim_get_current_buf()
@@ -1176,9 +1176,9 @@ vim.bo[{bufnr}] *vim.bo*
< <
vim.env *vim.env* vim.env *vim.env*
Environment variables defined in the editor session. See |expand-env| and Gets or sets environment variables in the current editor process. See
|:let-environment| for the Vimscript behavior. Invalid or unset key |expand-env| and |:let-environment| for the Vimscript behavior. Invalid or
returns `nil`. unset key returns `nil`.
Example: >lua Example: >lua
vim.env.FOO = 'bar' vim.env.FOO = 'bar'
@@ -1186,11 +1186,10 @@ vim.env *vim.env*
< <
vim.go *vim.go* vim.go *vim.go*
Get or set global |options|. Like `:setglobal`. Invalid key is an error. Gets or sets global |options|. Like `:setglobal`. Invalid key is an error.
Note: this is different from |vim.o| because this accesses the global Note: unlike |vim.o|, this accesses the global option value and thus is
option value and thus is mostly useful for use with |global-local| mostly useful with |global-local| options.
options.
Example: >lua Example: >lua
vim.go.cmdheight = 4 vim.go.cmdheight = 4
@@ -1199,7 +1198,7 @@ vim.go *vim.go*
< <
vim.o *vim.o* vim.o *vim.o*
Get or set |options|. Works like `:set`, so buffer/window-scoped options Gets or sets |options|. Works like `:set`, so buffer/window-scoped options
target the current buffer/window. Invalid key is an error. target the current buffer/window. Invalid key is an error.
Example: >lua Example: >lua
@@ -1209,14 +1208,12 @@ vim.o *vim.o*
< <
vim.wo[{winid}][{bufnr}] *vim.wo* vim.wo[{winid}][{bufnr}] *vim.wo*
Get or set window-scoped |options| for the window with handle {winid} and Gets or sets window-scoped |options| on window {winid} (or "current
buffer with number {bufnr}. Like `:setlocal` if setting a |global-local| window" if 0 or omitted) and buffer {bufnr} (0 for current buffer). Like
option or if {bufnr} is provided, like `:set` otherwise. If {winid} is `:setlocal` if setting a |global-local| option or if {bufnr} is specified,
omitted then the current window is used. Invalid {winid}, {bufnr} or key like `:set` otherwise. Invalid {winid}, {bufnr}, or key is an error.
is an error.
Note: only {bufnr} with value `0` (the current buffer in the window) is Note: only bufnr=0 (current window-buffer) is supported, currently.
supported.
Example: >lua Example: >lua
local winid = vim.api.nvim_get_current_win() local winid = vim.api.nvim_get_current_win()
@@ -2484,28 +2481,31 @@ vim.filetype.match({args}) *vim.filetype.match()*
============================================================================== ==============================================================================
Lua module: vim.fs *vim.fs* Lua module: vim.fs *vim.fs*
*vim.fs.copy()* *vim.fs.copy()*
Use |filecopy()| or |uv.fs_copyfile()| to performantly copy an existing file. Use |filecopy()| or |uv.fs_copyfile()| to performantly copy an existing file.
Example: >lua Example: >lua
vim.fn.filecopy('foo.txt', 'bar.txt') vim.fn.filecopy('foo.txt', 'bar.txt')
< <
*vim.fs.exists()* *vim.fs.exists()*
Use |uv.fs_stat()| to check a file's type, and whether it exists. Use |uv.fs_stat()| to check a file's type, and whether it exists.
Example: >lua Example: >lua
if vim.uv.fs_stat(file) then if vim.uv.fs_stat(file) then
vim.print('file exists') vim.print('file exists')
end end
< <
*vim.fs.read()* *vim.fs.read()*
You can use |readblob()| to get a file's contents without explicitly opening/closing it.
You can use |readblob()| to get a file's contents without explicitly
opening/closing it. Or use |io.lines()| to iterate lines in a text file.
Example: >lua Example: >lua
vim.print(vim.fn.readblob('.git/config')) vim.print(vim.fn.readblob('.git/config'))
< <
+1
View File
@@ -123,6 +123,7 @@ DIAGNOSTICS
EDITOR EDITOR
• |gf| and |<cfile>| support `file://…` URIs.
• |:log| opens log files. • |:log| opens log files.
EVENTS EVENTS
+10 -2
View File
@@ -1687,8 +1687,16 @@ A jump table for the options with a short description can be found at |Q_op|.
'ignorecase' is set without 'infercase'. 'ignorecase' is set without 'infercase'.
See also |preinserted()|. See also |preinserted()|.
preselect Selects the first completion item whose "preselect" preselect
field is set, if any. Takes precedence over "noselect". When one of |complete-items| has its "preselect" field set
(e.g., as indicated by an LSP server), select the first
such item in the |popupmenu-completion|. Takes precedence
over "noselect".
Unlike the implicit selection behavior (when "noselect" is
not set), this preserves the original sort order and
navigates to the preselect item rather than always
selecting the first item.
preview Show extra information about the currently selected preview Show extra information about the currently selected
completion in the preview window. Only works in completion in the preview window. Only works in
+1 -3
View File
@@ -361,7 +361,7 @@ Performing actions via `vim.pack` functions can trigger these events:
• *PackChangedPre* - before trying to change plugin's state. • *PackChangedPre* - before trying to change plugin's state.
• *PackChanged* - after plugin's state has changed. • *PackChanged* - after plugin's state has changed.
Each event populates the following |event-data| fields: The |event-data| has these keys (type: `vim.event.packchanged.data`):
• `active` - whether plugin was added via |vim.pack.add()| to current session. • `active` - whether plugin was added via |vim.pack.add()| to current session.
• `kind` - one of "install" (install on disk; before loading), "update" • `kind` - one of "install" (install on disk; before loading), "update"
(update already installed plugin; might be not loaded), "delete" (delete (update already installed plugin; might be not loaded), "delete" (delete
@@ -369,8 +369,6 @@ Each event populates the following |event-data| fields:
• `spec` - plugin's specification with defaults made explicit. • `spec` - plugin's specification with defaults made explicit.
• `path` - full path to plugin's directory. • `path` - full path to plugin's directory.
See `vim.event.packchanged.data` and `vim.event.packchangedpre.data`.
These events can be used to execute plugin hooks. For example: >lua These events can be used to execute plugin hooks. For example: >lua
local hooks = function(ev) local hooks = function(ev)
-- Use available |event-data| -- Use available |event-data|
+12 -18
View File
@@ -134,9 +134,8 @@ local function get_options_info(name)
return info return info
end end
--- Environment variables defined in the editor session. --- Gets or sets environment variables in the current editor process. See |expand-env| and
--- See |expand-env| and |:let-environment| for the Vimscript behavior. --- |:let-environment| for the Vimscript behavior. Invalid or unset key returns `nil`.
--- Invalid or unset key returns `nil`.
--- ---
--- Example: --- Example:
--- ---
@@ -229,7 +228,7 @@ end
--- global value of a |global-local| option, see |:setglobal|. --- global value of a |global-local| option, see |:setglobal|.
--- </pre> --- </pre>
--- Get or set |options|. Works like `:set`, so buffer/window-scoped options target the current --- Gets or sets |options|. Works like `:set`, so buffer/window-scoped options target the current
--- buffer/window. Invalid key is an error. --- buffer/window. Invalid key is an error.
--- ---
--- Example: --- Example:
@@ -248,12 +247,10 @@ vim.o = setmetatable({}, {
end, end,
}) })
--- Get or set global |options|. Like `:setglobal`. Invalid key is --- Gets or sets global |options|. Like `:setglobal`. Invalid key is an error.
--- an error.
--- ---
--- Note: this is different from |vim.o| because this accesses the global --- Note: unlike |vim.o|, this accesses the global option value and thus is mostly useful
--- option value and thus is mostly useful for use with |global-local| --- with |global-local| options.
--- options.
--- ---
--- Example: --- Example:
--- ---
@@ -271,9 +268,8 @@ vim.go = setmetatable({}, {
end, end,
}) })
--- Get or set buffer-scoped |options| for the buffer with number {bufnr}. --- Gets or sets buffer-scoped |options| on buffer {bufnr} (or "current buffer" if 0 or omitted). Like
--- Like `:setlocal`. If {bufnr} is omitted then the current buffer is used. --- `:setlocal`. Invalid {bufnr} or key is an error.
--- Invalid {bufnr} or key is an error.
--- ---
--- Example: --- Example:
--- ---
@@ -285,13 +281,11 @@ vim.go = setmetatable({}, {
--- ``` --- ```
vim.bo = new_buf_opt_accessor() vim.bo = new_buf_opt_accessor()
--- Get or set window-scoped |options| for the window with handle {winid} and --- Gets or sets window-scoped |options| on window {winid} (or "current window" if 0 or omitted) and
--- buffer with number {bufnr}. Like `:setlocal` if setting a |global-local| option --- buffer {bufnr} (0 for current buffer). Like `:setlocal` if setting a |global-local| option or if
--- or if {bufnr} is provided, like `:set` otherwise. If {winid} is omitted then --- {bufnr} is specified, like `:set` otherwise. Invalid {winid}, {bufnr}, or key is an error.
--- the current window is used. Invalid {winid}, {bufnr} or key is an error.
--- ---
--- Note: only {bufnr} with value `0` (the current buffer in the window) is --- Note: only bufnr=0 (current window-buffer) is supported, currently.
--- supported.
--- ---
--- Example: --- Example:
--- ---
+8 -10
View File
@@ -1879,16 +1879,14 @@ function vim.api.nvim_open_term(buf, opts) end
--- - win: `window-ID` target window. Can be in a different tab page. Determines the window to --- - win: `window-ID` target window. Can be in a different tab page. Determines the window to
--- split (negative values act like `:topleft`, `:botright`), the relative window for a --- split (negative values act like `:topleft`, `:botright`), the relative window for a
--- `relative="win"` float, or just the target tab page (inferred from the window) for others. --- `relative="win"` float, or just the target tab page (inferred from the window) for others.
--- - zindex: Stacking order. floats with higher `zindex` go on top on --- - zindex: (positive integer, default: 50) Stacking order. Floats with higher `zindex` overlay
--- floats with lower indices. Must be larger than zero. The --- floats with lower indices. Below 100 is recommended, unless there is a good reason to
--- following screen elements have hard-coded z-indices: --- overshadow builtin elements. The cursor is dimmed if an unfocused float above the cursor
--- - 100: insert completion popupmenu --- exceeds the zindex of the current window by 50. These screen elements have hard-coded
--- - 200: message scrollback --- z-indices:
--- - 250: cmdline completion popupmenu (when wildoptions+=pum) --- - 100: `ins-completion-menu` popupmenu
--- The default value for floats are 50. In general, values below 100 are --- - 200: message scrollback (`pager`)
--- recommended, unless there is a good reason to overshadow builtin --- - 250: `cmdline-completion` popupmenu (wildoptions=pum)
--- elements. The cursor is dimmed if an unfocused float above the cursor
--- exceeds the zindex of the current window by 50.
--- - _cmdline_offset: (EXPERIMENTAL) When provided, anchor the `cmdline-completion` --- - _cmdline_offset: (EXPERIMENTAL) When provided, anchor the `cmdline-completion`
--- popupmenu to this window, with an offset in screen cell width. --- popupmenu to this window, with an offset in screen cell width.
--- @return integer # |window-ID|, or 0 on error --- @return integer # |window-ID|, or 0 on error
+3 -2
View File
@@ -1,8 +1,9 @@
--- @meta _ --- @meta _
-- This file is NOT generated, edit it directly. See also _meta/api_keysets.gen.lua. -- This file is NOT generated, edit it directly. See also _meta/api_keysets.gen.lua.
error('Cannot require a meta file') error('Cannot require a meta file')
--- Extra types we can't generate keysets for --- Extra types we don't define keysets for.
--- @class vim.api.keyset.extmark_details --- @class vim.api.keyset.extmark_details
--- @field ns_id integer --- @field ns_id integer
@@ -75,7 +76,7 @@ error('Cannot require a meta file')
--- @field match string expanded value of <amatch> --- @field match string expanded value of <amatch>
--- @field buf integer expanded value of <abuf> --- @field buf integer expanded value of <abuf>
--- @field file string expanded value of <afile> --- @field file string expanded value of <afile>
--- @field data? any arbitrary data passed from |nvim_exec_autocmds()| *event-data* --- @field data? any arbitrary data passed from |nvim_exec_autocmds()|
--- @class vim.api.keyset.create_user_command.command_args --- @class vim.api.keyset.create_user_command.command_args
--- @field name string Command name --- @field name string Command name
+3
View File
@@ -1,4 +1,7 @@
--- @meta --- @meta
-- This file is NOT generated, edit it directly.
--
-- See also `vim.api.keyset.events` in `api_keysets.gen.lua`.
error('Cannot require a meta file') error('Cannot require a meta file')
--- @class vim.event.lspattach.data --- @class vim.event.lspattach.data
+10 -2
View File
@@ -1203,8 +1203,16 @@ vim.go.cia = vim.go.completeitemalign
--- 'ignorecase' is set without 'infercase'. --- 'ignorecase' is set without 'infercase'.
--- See also `preinserted()`. --- See also `preinserted()`.
--- ---
--- preselect Selects the first completion item whose "preselect" --- preselect
--- field is set, if any. Takes precedence over "noselect". --- When one of `complete-items` has its "preselect" field set
--- (e.g., as indicated by an LSP server), select the first
--- such item in the `popupmenu-completion`. Takes precedence
--- over "noselect".
---
--- Unlike the implicit selection behavior (when "noselect" is
--- not set), this preserves the original sort order and
--- navigates to the preselect item rather than always
--- selecting the first item.
--- ---
--- preview Show extra information about the currently selected --- preview Show extra information about the currently selected
--- completion in the preview window. Only works in --- completion in the preview window. Only works in
+19 -16
View File
@@ -1,32 +1,35 @@
--- @brief <pre>help --- @brief
--- *vim.fs.copy()* --- [vim.fs.copy()]()
---
--- Use |filecopy()| or |uv.fs_copyfile()| to performantly copy an existing file. --- Use |filecopy()| or |uv.fs_copyfile()| to performantly copy an existing file.
--- ---
--- Example: --- Example:
--- ---
--- >lua --- ```lua
--- vim.fn.filecopy('foo.txt', 'bar.txt') --- vim.fn.filecopy('foo.txt', 'bar.txt')
--- < --- ```
---
--- [vim.fs.exists()]()
--- ---
--- *vim.fs.exists()*
--- Use |uv.fs_stat()| to check a file's type, and whether it exists. --- Use |uv.fs_stat()| to check a file's type, and whether it exists.
--- ---
--- Example: --- Example:
--- ---
--- >lua --- ```lua
--- if vim.uv.fs_stat(file) then --- if vim.uv.fs_stat(file) then
--- vim.print('file exists') --- vim.print('file exists')
--- end --- end
--- < --- ```
---
--- [vim.fs.read()]()
--- ---
--- *vim.fs.read()*
--- You can use |readblob()| to get a file's contents without explicitly opening/closing it. --- You can use |readblob()| to get a file's contents without explicitly opening/closing it.
--- Or use |io.lines()| to iterate lines in a text file.
--- ---
--- Example: --- Example:
--- --- ```lua
--- >lua --- vim.print(vim.fn.readblob('.git/config'))
--- vim.print(vim.fn.readblob('.git/config')) --- ```
--- <
local uv = vim.uv local uv = vim.uv
+13
View File
@@ -53,6 +53,19 @@ local all_clients = {}
--- absolute or on `$PATH`, shell constructs like "~" are not expanded), or function that creates an --- absolute or on `$PATH`, shell constructs like "~" are not expanded), or function that creates an
--- RPC client (or an in-process |lsp-server|). Function receives a `dispatchers` table and the --- RPC client (or an in-process |lsp-server|). Function receives a `dispatchers` table and the
--- resolved `config`, and must return an object in the form of |vim.lsp.rpc.Client|. --- resolved `config`, and must return an object in the form of |vim.lsp.rpc.Client|.
---
--- Example (list):
--- ```lua
--- cmd = { 'flow', 'lsp' }
--- ```
--- Example (function):
--- ```lua
--- cmd = function(dispatchers, config)
--- local cmd = vim.fn.executable('flow') == 1 and { 'flow', 'lsp' } or { 'npx', '--no-install', 'flow', 'lsp' }
--- return vim.lsp.rpc.start(cmd, dispatchers)
--- end
--- ```
---
--- - See |vim.lsp.rpc.request()| |vim.lsp.rpc.notify()| --- - See |vim.lsp.rpc.request()| |vim.lsp.rpc.notify()|
--- - For TCP there is a builtin RPC client factory: |vim.lsp.rpc.connect()| --- - For TCP there is a builtin RPC client factory: |vim.lsp.rpc.connect()|
--- @field cmd string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers, config: vim.lsp.ClientConfig): vim.lsp.rpc.Client --- @field cmd string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers, config: vim.lsp.ClientConfig): vim.lsp.rpc.Client
+1 -3
View File
@@ -167,7 +167,7 @@
---- [PackChangedPre]() - before trying to change plugin's state. ---- [PackChangedPre]() - before trying to change plugin's state.
---- [PackChanged]() - after plugin's state has changed. ---- [PackChanged]() - after plugin's state has changed.
--- ---
---Each event populates the following |event-data| fields: ---The |event-data| has these keys (type: `vim.event.packchanged.data`):
---- `active` - whether plugin was added via |vim.pack.add()| to current session. ---- `active` - whether plugin was added via |vim.pack.add()| to current session.
---- `kind` - one of "install" (install on disk; before loading), ---- `kind` - one of "install" (install on disk; before loading),
--- "update" (update already installed plugin; might be not loaded), --- "update" (update already installed plugin; might be not loaded),
@@ -175,8 +175,6 @@
---- `spec` - plugin's specification with defaults made explicit. ---- `spec` - plugin's specification with defaults made explicit.
---- `path` - full path to plugin's directory. ---- `path` - full path to plugin's directory.
--- ---
---See `vim.event.packchanged.data` and `vim.event.packchangedpre.data`.
---
--- These events can be used to execute plugin hooks. For example: --- These events can be used to execute plugin hooks. For example:
---```lua ---```lua
---local hooks = function(ev) ---local hooks = function(ev)
+3 -10
View File
@@ -304,16 +304,9 @@ function M._get_urls()
end end
do do
---@class ProgressMessage
---@field id? number|string ID of the progress message
---@field title? string Title of the progress message
---@field status string Status: "running" | "success" | "failed" | "cancel"
---@field percent? integer Percent complete (0100)
---@private
--- Cache of active progress messages, keyed by msg_id --- Cache of active progress messages, keyed by msg_id
--- TODO(justinmk): visibility of "stale" (never-finished) Progress. https://github.com/neovim/neovim/pull/35428#discussion_r2942696157 --- TODO(justinmk): visibility of "stale" (never-finished) Progress. https://github.com/neovim/neovim/pull/35428#discussion_r2942696157
---@type table<integer, ProgressMessage> ---@type table<integer, vim.event.progress.data>
local progress = {} local progress = {}
-- store progress events -- store progress events
@@ -325,7 +318,7 @@ do
progress_autocmd = vim.api.nvim_create_autocmd('Progress', { progress_autocmd = vim.api.nvim_create_autocmd('Progress', {
group = progress_group, group = progress_group,
desc = 'Tracks progress messages for vim.ui.progress_status()', desc = 'Tracks progress messages for vim.ui.progress_status()',
---@param ev {data: {id: integer, title: string, status: string, percent: integer}} ---@param ev {data: vim.event.progress.data}
callback = function(ev) callback = function(ev)
if not ev.data or not ev.data.id then if not ev.data or not ev.data.id then
return return
@@ -349,7 +342,7 @@ do
--- Gets a status description summarizing currently running progress messages. --- Gets a status description summarizing currently running progress messages.
--- - If none: returns empty string --- - If none: returns empty string
--- - If N item running: "AVG%(N)" --- - If N item running: "AVG%(N)"
---@param running ProgressMessage[] ---@param running vim.event.progress.data[]
---@return string ---@return string
local function progress_status_fmt(running) local function progress_status_fmt(running)
local count = #running local count = #running
+8 -10
View File
@@ -186,16 +186,14 @@
/// - win: |window-ID| target window. Can be in a different tab page. Determines the window to /// - win: |window-ID| target window. Can be in a different tab page. Determines the window to
/// split (negative values act like |:topleft|, |:botright|), the relative window for a /// split (negative values act like |:topleft|, |:botright|), the relative window for a
/// `relative="win"` float, or just the target tab page (inferred from the window) for others. /// `relative="win"` float, or just the target tab page (inferred from the window) for others.
/// - zindex: Stacking order. floats with higher `zindex` go on top on /// - zindex: (positive integer, default: 50) Stacking order. Floats with higher `zindex` overlay
/// floats with lower indices. Must be larger than zero. The /// floats with lower indices. Below 100 is recommended, unless there is a good reason to
/// following screen elements have hard-coded z-indices: /// overshadow builtin elements. The cursor is dimmed if an unfocused float above the cursor
/// - 100: insert completion popupmenu /// exceeds the zindex of the current window by 50. These screen elements have hard-coded
/// - 200: message scrollback /// z-indices:
/// - 250: cmdline completion popupmenu (when wildoptions+=pum) /// - 100: |ins-completion-menu| popupmenu
/// The default value for floats are 50. In general, values below 100 are /// - 200: message scrollback (|pager|)
/// recommended, unless there is a good reason to overshadow builtin /// - 250: |cmdline-completion| popupmenu (wildoptions=pum)
/// elements. The cursor is dimmed if an unfocused float above the cursor
/// exceeds the zindex of the current window by 50.
/// - _cmdline_offset: (EXPERIMENTAL) When provided, anchor the |cmdline-completion| /// - _cmdline_offset: (EXPERIMENTAL) When provided, anchor the |cmdline-completion|
/// popupmenu to this window, with an offset in screen cell width. /// popupmenu to this window, with an offset in screen cell width.
/// ///
+10 -2
View File
@@ -1674,8 +1674,16 @@ local options = {
'ignorecase' is set without 'infercase'. 'ignorecase' is set without 'infercase'.
See also |preinserted()|. See also |preinserted()|.
preselect Selects the first completion item whose "preselect" preselect
field is set, if any. Takes precedence over "noselect". When one of |complete-items| has its "preselect" field set
(e.g., as indicated by an LSP server), select the first
such item in the |popupmenu-completion|. Takes precedence
over "noselect".
Unlike the implicit selection behavior (when "noselect" is
not set), this preserves the original sort order and
navigates to the preselect item rather than always
selecting the first item.
preview Show extra information about the currently selected preview Show extra information about the currently selected
completion in the preview window. Only works in completion in the preview window. Only works in
+14 -7
View File
@@ -1238,6 +1238,9 @@ describe('vim.lsp.util', function()
' @see `nvim_buf_detach()`', ' @see `nvim_buf_detach()`',
' @see `api-buffer-updates-lua`', ' @see `api-buffer-updates-lua`',
'', '',
-- For each @param/@return: #30695
-- - Separate each by one empty line.
-- - Remove all other blank lines.
'@*param* `buffer` — Buffer handle, or 0 for current buffer', '@*param* `buffer` — Buffer handle, or 0 for current buffer',
'', '',
'@*param* `send_buffer` — True if whole buffer.', '@*param* `send_buffer` — True if whole buffer.',
@@ -1300,7 +1303,7 @@ describe('vim.lsp.util', function()
before_each(function() before_each(function()
local _ = Screen.new(80, 80) local _ = Screen.new(80, 80)
feed('79i<CR><Esc>') feed('79i<CR><Esc>') -- fill screen with empty lines
end) end)
describe('when on the first line it places window below', function() describe('when on the first line it places window below', function()
@@ -1393,26 +1396,25 @@ describe('vim.lsp.util', function()
end) end)
describe('open_floating_preview', function() describe('open_floating_preview', function()
local curbuf
before_each(function() before_each(function()
Screen.new(10, 10) Screen.new(10, 10)
feed('9i<CR><Esc>G4k') feed('9i<CR><Esc>G4k')
curbuf = api.nvim_get_current_buf()
end) end)
local var_name = 'lsp_floating_preview' local var_name = 'lsp_floating_preview'
local curbuf = api.nvim_get_current_buf()
it('clean bufvar after fclose', function() it('after fclose', function()
exec_lua(function() exec_lua(function()
vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 }) vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 })
end) end)
eq(true, api.nvim_win_is_valid(api.nvim_buf_get_var(curbuf, var_name))) eq(true, api.nvim_win_is_valid(api.nvim_buf_get_var(curbuf, var_name)))
command('fclose') command('fclose')
-- b:lsp_floating_preview should be cleared.
eq('Key not found: lsp_floating_preview', pcall_err(api.nvim_buf_get_var, curbuf, var_name)) eq('Key not found: lsp_floating_preview', pcall_err(api.nvim_buf_get_var, curbuf, var_name))
end) end)
it('clean bufvar after CursorMoved', function() it('after CursorMoved', function()
local result, winfixbuf = exec_lua(function() local result, winfixbuf = exec_lua(function()
vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 }) vim.lsp.util.open_floating_preview({ 'test' }, '', { height = 5, width = 2 })
local winnr = vim.b[vim.api.nvim_get_current_buf()].lsp_floating_preview local winnr = vim.b[vim.api.nvim_get_current_buf()].lsp_floating_preview
@@ -1422,7 +1424,9 @@ describe('vim.lsp.util', function()
return result, winfixbuf return result, winfixbuf
end) end)
eq(true, result) eq(true, result)
-- 'winfixbuf' should be set. #39058
eq(true, winfixbuf) eq(true, winfixbuf)
-- b:lsp_floating_preview should be cleared.
eq('Key not found: lsp_floating_preview', pcall_err(api.nvim_buf_get_var, curbuf, var_name)) eq('Key not found: lsp_floating_preview', pcall_err(api.nvim_buf_get_var, curbuf, var_name))
end) end)
end) end)
@@ -1481,6 +1485,7 @@ describe('vim.lsp.util', function()
{1:~ }|*9 {1:~ }|*9
| |
]]) ]])
-- Entering window keeps lines concealed and doesn't end up below inner window size.
feed('<C-w>wG') feed('<C-w>wG')
screen:expect([[ screen:expect([[
| |
@@ -1490,8 +1495,9 @@ describe('vim.lsp.util', function()
{1:~ }|*9 {1:~ }|*9
| |
]]) ]])
-- Correct height when float inherits 'conceallevel' >= 2 #32639
command('close | set conceallevel=2') command('close | set conceallevel=2')
feed('<Ignore>') feed('<Ignore>') -- Prevent CursorMoved closing the next float immediately
exec_lua([[ exec_lua([[
vim.lsp.util.open_floating_preview({ '```lua', 'local foo', '```' }, 'markdown', { vim.lsp.util.open_floating_preview({ '```lua', 'local foo', '```' }, 'markdown', {
border = 'single', border = 'single',
@@ -1506,6 +1512,7 @@ describe('vim.lsp.util', function()
{1:~ }|*9 {1:~ }|*9
| |
]]) ]])
-- This tests the valid winline code path (why doesn't the above?).
exec_lua([[ exec_lua([[
vim.cmd.only() vim.cmd.only()
vim.lsp.util.open_floating_preview({ 'foo', '```lua', 'local bar', '```' }, 'markdown', { vim.lsp.util.open_floating_preview({ 'foo', '```lua', 'local bar', '```' }, 'markdown', {