Compare commits

...

189 Commits

Author SHA1 Message Date
Justin M. Keyes
045b1d7f90 fixup! fixup! fixup! feat(jobs): jobstart(…,{term:true}), deprecate termopen() 2024-12-18 16:35:31 +01:00
Justin M. Keyes
e340b4e113 fixup! fixup! feat(jobs): jobstart(…,{term:true}), deprecate termopen() 2024-12-18 16:28:55 +01:00
Justin M. Keyes
f7890bb005 fixup! feat(jobs): jobstart(…,{term:true}), deprecate termopen() 2024-12-18 16:25:51 +01:00
Justin M. Keyes
4c346f677e feat(jobs): jobstart(…,{term:true}), deprecate termopen()
Problem:
`termopen` has long been a superficial wrapper around `jobstart`, and
has no real purpose. Also, `vim.system` and `nvim_open_term` presumably
will replace all features of `jobstart` and `termopen`, so centralizing
the logic will help with that.

Solution:
- Introduce "term" flag of `jobstart`.
- Deprecate `termopen`.
2024-12-18 15:42:04 +01:00
zeertzjq
51c380238c
Merge pull request #31615 from zeertzjq/vim-9.1.0936
vim-patch:9.1.{0936,0941,0942}: ComplMatchIns highlight
2024-12-18 08:40:23 +08:00
zeertzjq
b7da54aa9e vim-patch:9.1.0942: a few typos were found
Problem:  a few typos were found
Solution: fix them (zeertzjq)

closes: vim/vim#16232

d32bf0a067
2024-12-18 08:15:31 +08:00
zeertzjq
2f7b385f2e vim-patch:9.1.0941: ComplMatchIns doesn't work after multibyte chars
Problem:  ComplMatchIns doesn't work after multibyte chars
          (after v9.1.0936)
Solution: Use (ptr - line) instead of wlv.col (zeertzjq).

closes: vim/vim#16233

f4ccada5c3
2024-12-18 08:15:31 +08:00
zeertzjq
c830901e8c vim-patch:9.1.0936: cannot highlight completed text
Problem:  cannot highlight completed text
Solution: (optionally) highlight auto-completed text using the
          ComplMatchIns highlight group (glepnir)

closes: vim/vim#16173

6a38aff218

Co-authored-by: glepnir <glephunter@gmail.com>
2024-12-18 08:15:31 +08:00
Gregory Anders
0dd933265f
feat(terminal)!: cursor shape and blink (#31562)
When a terminal application running inside the terminal emulator sets
the cursor shape or blink status of the cursor, update the cursor in the
parent terminal to match.

This removes the "virtual cursor" that has been in use by the terminal
emulator since the beginning. The original rationale for using the
virtual cursor was to avoid having to support additional UI methods to
change the cursor color for other (non-TUI) UIs, instead relying on the
TermCursor and TermCursorNC highlight groups.

The TermCursor highlight group is now used in the default 'guicursor'
value, which has a new entry for Terminal mode. However, the
TermCursorNC highlight group is no longer supported: since terminal
windows now use the real cursor, when the window is not focused there is
no cursor displayed in the window at all, so there is nothing to
highlight. Users can still use the StatusLineTermNC highlight group to
differentiate non-focused terminal windows.

BREAKING CHANGE: The TermCursorNC highlight group is no longer supported.
2024-12-17 07:11:41 -06:00
Shougo
df367cf91c
test: unreliable test "messages &messagesopt wait" #31548 2024-12-17 04:19:55 -08:00
luukvbaal
6bf2a6fc5b
refactor(api): always use TRY_WRAP #31600
Problem:  Two separate try/end wrappers, that only marginally differ by
          restoring a few variables. Wrappers that don't restore
          previous state are dangerous to use in "api-fast" functions.
Solution: Remove wrappers that don't restore the previous state.
          Always use TRY_WRAP.
2024-12-17 04:12:22 -08:00
zeertzjq
b03e790cdd
vim-patch:9.1.0934: hard to view an existing buffer in the preview window (#31605)
Problem:  hard to view an existing buffer in the preview window
Solution: add the :pbuffer command (Yinzuo Jiang)

Similar as `:pedit` and `:buffer` command. `:pbuffer` edits buffer [N]
from the buffer list in the preview window.

`:pbuffer` can also open special buffer, for example terminal buffer.

closes: vim/vim#16222

a2a2fe841e

Cherry-pick Test_popup_and_previewwindow_dump() changes from patch
9.0.0625.
Cherry-pick Run_noroom_for_newwindow_test() changes from patches
8.2.0432 and 9.0.0363.

Co-authored-by: Yinzuo Jiang <jiangyinzuo@foxmail.com>
2024-12-17 03:34:30 +00:00
zeertzjq
15153c4cd5
vim-patch:9.1.0938: exclusive selection not respected when re-selecting block mode (#31603)
Problem:  exclusive selection not respected when re-selecting block mode
          (Matt Ellis)
Solution: advance selection by another character when using
          selection=exclusive and visual block mode

fixes: vim/vim#16202
closes: vim/vim#16219

bb95589473

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-17 09:03:26 +08:00
zeertzjq
137308a3c9
Merge pull request #31602 from zeertzjq/vim-0a4e57f
vim-patch: doc updates
2024-12-17 09:01:59 +08:00
zeertzjq
7d082d4816 vim-patch:3920bb4: runtime(doc): document how to minimize fold computation costs
closes: vim/vim#16224

3920bb4356

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
2024-12-17 08:27:44 +08:00
zeertzjq
59f38ef3c4 vim-patch:0a4e57f: runtime(doc): fix a few minor errors from the last doc updates
1) move the section at :h inclusive-motion-selection-exclusive a few
lines below, so that it doesn't live in between the 2 exceptions.

2) remove the tag :h :!-range. It's not accurate (because it is actually
a filter) and this command is already described at :h :range!

0a4e57f44a

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-17 08:21:31 +08:00
zeertzjq
98e3610316 vim-patch:41d6de2: runtime(doc): update the change.txt help file
41d6de2974

Co-authored-by: Antonio Giovanni Colombo <azc100@gmail.com>
2024-12-17 08:20:18 +08:00
Justin M. Keyes
022449b522
fix(api): generic error messages, not using TRY_WRAP #31596
Problem:
- API functions using `try_start` directly, do not surface the
  underlying error message, and instead show generic messages.
- Error-handling code is duplicated in the API impl.
- Failure modes are not tested.

Solution:
- Use `TRY_WRAP`.
- Add tests.
2024-12-16 08:34:16 -08:00
Christian Clason
fb8372adb3 build(deps): bump luajit to HEAD - f73e649a9 2024-12-16 17:08:52 +01:00
Lewis Russell
47f2769b46 fix(Man): completion on Mac
Problem:
`man -w` does not work on recent versions of MacOs.

Solution:
Make it so an empty result is interpreted as an error unless silent=true
2024-12-16 16:05:08 +00:00
dundargoc
b5c0290803 ci(build.yml): disable security restriction
A new security restriction in Ubuntu 24.04 prevents users from using
`unshare`, so we need to disable it in order for the test to work
properly.
2024-12-16 16:26:19 +01:00
Juan Cruz De La Torre
6c975515c5
fix(diagnostic): vim.diagnostic.setqflist() opens loclist on first call #31585
Problem:
Regression from de794f2d24: `vim.diagnostic.setqflist{open=true}` attempts to
open the location list instead of the diagnostics quickfix list if it didn't
exist before. This is because we are using `qf_id` to decide which to open, but
`qf_id=nil` when there is no existing diagnostics quickfix list with a given
title ("Diagnostics" by default).

Solution:
- Revert to using `loclist` to decide which to open.
- Add tests.
2024-12-16 06:38:57 -08:00
bfredl
798f928479
Merge pull request #31539 from bfredl/wininfo
refactor(wininfo): change wininfo from a linked list to an array
2024-12-16 13:24:09 +01:00
Justin M. Keyes
167a2383b9
fix(api): not using TRY_WRAP, generic error messages #31595
Problem:
- API functions using `try_start` directly instead of `TRY_WRAP`, do not
  surface the underlying error message, and instead show generic things
  like "Failed to set buffer".
- Error handling code is duplicated in the API impl, instead of
  delegating to the vim buffer/window handling logic.

Solution:
- Use `TRY_WRAP`.
2024-12-16 04:00:20 -08:00
bfredl
2d6f57b289 refactor(wininfo): change wininfo from a linked list to an array
"wininfo" is going to be my next victim. The main problem with wininfo
is that it is "all or nothing", i e either all state about a buffer in a
window is considered valid or none of it is. This needs to be fixed to
address some long running grievances.

For now this is just a warmup: refactor it from a linked list to a
vector.
2024-12-16 12:46:59 +01:00
Tomasz N
9c6a3703bb
fix(messages): no message kind for :undo messages #31590
Problem: cannot handle `:undo` and `:redo` messages in a special way,
e.g. replace one by another.

Solution: add `undo` kind.
2024-12-16 03:07:27 -08:00
phanium
01a97d2ad7
fix(api): nvim_win_set_buf(0, 0) fails if 'winfixbuf' is set #31576
## Problem
With 'winfixbuf' enabled, `nvim_win_set_buf` and `nvim_set_current_buf` fail
even if targeting the already-current buffer.

    vim.wo.winfixbuf = true
    vim.api.nvim_win_set_buf(0, 0)
    vim.api.nvim_set_current_buf(0)

Solution:
Check for this condition.
2024-12-16 00:59:24 -08:00
Christian Clason
cc38630d39 vim-patch:9.1.0929: filetype: lalrpop files are not recognized
Problem:  filetype: lalrpop files are not recognized
Solution: detect '*.lalrpop' files as lalrpop filetype
          (David Thievon)

References:
https://github.com/lalrpop/lalrpop

closes: vim/vim#16223

5a2e0cf5f1

Co-authored-by: David Thievon <pdkfan@gmail.com>
2024-12-16 00:19:16 +01:00
Christian Clason
6c2c77b128 vim-patch:9.1.0926: filetype: Pixi lock files are not recognized
Problem:  filetype: Pixi lock files are not recognized
Solution: detect "pixi.lock" file as yaml filetype
          (Brandon Maier)

Reference:
https://pixi.sh/latest/features/lockfile/

closes: vim/vim#16212

7d1bb90dcf

Co-authored-by: Brandon Maier <brandon.maier@gmail.com>
2024-12-15 12:42:27 +01:00
Christian Clason
820984daea build(deps): bump tree-sitter to v0.24.5 2024-12-15 12:35:11 +01:00
zeertzjq
852b6a6bce
vim-patch:9.1.0927: style issues in insexpand.c (#31581)
Problem:  style issues in insexpand.c
Solution: add braces, use ternary operator to improve style
          (glepnir)

closes: vim/vim#16210

6e19993991

vim-patch:9.1.0922: wrong MIN macro in popupmenu.c
vim-patch:9.1.0923: too many strlen() calls in filepath.c
vim-patch:9.1.0924: patch 9.1.0923 causes issues

Co-authored-by: glepnir <glephunter@gmail.com>
2024-12-15 08:19:18 +08:00
zeertzjq
805b84c619
Merge pull request #31580 from zeertzjq/vim-ed89206
vim-patch: doc updates
2024-12-15 08:16:03 +08:00
zeertzjq
3406b00911 vim-patch:fbe9a69: runtime(doc): Add a reference to |++opt| and |+cmd| at :h :pedit
closes: vim/vim#16217

fbe9a6903a

Co-authored-by: Yinzuo Jiang <jiangyinzuo@foxmail.com>
2024-12-15 07:10:12 +08:00
zeertzjq
caa93b5e1e vim-patch:ed89206: runtime(doc): add a note about inclusive motions and exclusive selection
related: vim/vim#16202

ed89206efe

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-15 07:09:39 +08:00
luukvbaal
433b342baa
feat(ui): sign/statuscolumn can combine highlight attrs #31575
Problem:
Since e049c6e4c0, most statusline-like UI elements can combine
highlight attrs, except for sign/statuscolumn.

Solution:
Implement for sign/statuscolumn.
2024-12-14 10:21:50 -08:00
Colin Kennedy
f9dd682621 docs(annotations): added ---@generic support 2024-12-13 17:05:38 +00:00
Justin M. Keyes
65b1733405
Revert "fix(Man.lua): trigger completion even without arguments" #31572
This reverts commit 7940ec6913.
2024-12-13 06:46:40 -08:00
Lewis Russell
9c20342297 fix(lsp): reuse client if configs match and no root dir
Problem:
An LSP configuration that creates client with no root_dir or
workspace_folders can result in vim.lsp.enable attaching to it multiple
times.

Solution:
When checking existing clients, reuse a client if it wasn't initially
configured have any workspace_folders. This more closely matches the
behaviour we had prior to d9235ef
2024-12-13 14:36:24 +00:00
Luca Saccarola
7940ec6913
fix(man.lua): :Man <tab> does not complete #31569
closes: #31512
2024-12-13 06:26:20 -08:00
zeertzjq
c0ae39ee53
Merge pull request #31566 from zeertzjq/vim-9.1.0921
vim-patch:9.1.{0921,0922}
2024-12-13 21:58:18 +08:00
zeertzjq
1386d36e76 vim-patch:9.1.092: vim-patch:9.1.0923: wrong MIN macro in popupmenu.c
Problem:  wrong MIN macro in popupmenu.c (after v9.1.0921)
          (zeertzjq)
Solution: change it to MAX()

618c4d36ca

Co-authored-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: glepnir <glephunter@gmail.com>
2024-12-13 21:33:26 +08:00
zeertzjq
8a0b203875 vim-patch:9.1.0921: popupmenu logic is a bit convoluted
Problem:  popupmenu logic is a bit convoluted
Solution: slightly refactor logic and use MIN/MAX() macros to simplify
          (glepnir)

Define the MAX/MIN macros. Since we support some older platforms, C
compilers may not be as smart. This helps reduce unnecessary if
statements and redundant ternary expressions. Pre-calculate some
expressions by defining variables. Remove unnecessary parentheses.
Adjust certain lines to avoid exceeding 80 columns.

closes: vim/vim#16205

c942f84aad

Co-authored-by: glepnir <glephunter@gmail.com>
2024-12-13 20:01:26 +08:00
Christian Clason
3e3a984300 vim-patch:5c42c77: runtime(netrw): do not pollute search history with symlinks
fixes: vim/vim#16206

5c42c77315

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-13 09:38:19 +01:00
Christian Clason
2e73ba102a vim-patch:9.1.0919: filetype: some assembler files are not recognized
Problem:  filetype: some assembler are files not recognized
Solution: detect '*.nasm' files as nasm filetype and '*.masm' as masm
          filetype (Wu, Zhenyu)

closes: vim/vim#16194

d66d68763d

Co-authored-by: Wu, Zhenyu <wuzhenyu@ustc.edu>
2024-12-13 09:38:08 +01:00
glepnir
17383870dd
fix(float): re-sort layers when grid zindex changed #30259
Problem: when zindex is changed in vim.schedule the zindex sort in
layers not changed.

Solution: resort layers when zindex changed.
2024-12-12 02:45:57 -08:00
Jeremy Fleischman
de794f2d24
fix(diagnostic): broken variable reference #31557 2024-12-12 02:41:57 -08:00
Lewis Russell
130f4344cf refactor(lsp/rpc): move transport logic to separate module 2024-12-12 09:52:08 +00:00
Jeremy Fleischman
5eda7aafe9
fix(diagnostic): setqflist() is stuck after vim.lsp.buf.document_symbol #31553
Previously, when updating the quickfix diagnostics list, we'd update it,
and then open the quickfix buffer, but there was no guarantee that the
quickfix buffer would be displaying the quickfix diagnostics list (it
could very possibly be displaying some other quickfix list!).

This fixes things so we first select the quickfix list before opening the
quickfix buffer. If `open` is not specified, the behavior is the same as
before: we update the diagnostics quickfix list, but do not navigate to
it.

fixes https://github.com/neovim/neovim/issues/31540
2024-12-11 17:32:07 -08:00
Jeremy Fleischman
21961967ff
feat(diagnostic): update quickfix list by title #31486
Previously, there was a singleton diagnostics quickfix list. Now there's
effectively one per title (up to vim's internal limit on quickfix
lists).

Suggested by mfussenegger https://github.com/neovim/neovim/pull/30868#pullrequestreview-2385761374.
2024-12-11 17:29:54 -08:00
Jonny Kong
442d338cb5
fix(uri): uri_encode encodes brackets incorrectly for RFC2732 #31284
**Problem:**
The brackets in the RFC2732 regular expression are currently unescaped,
causing them to be misinterpreted as special characters denoting
character groups rather than as literal characters.

**Solution:**
Escape the brackets.
Fix #31270
2024-12-11 05:48:17 -08:00
glepnir
ff1791c9e5
fix(float): close preview float window when no selected #29745
Problem: Float preview window still exist when back at original.
Or no info item is selected.

Solution: if selected is -1 or no info is selected, if float preview
window exist close it first.
2024-12-11 05:20:10 -08:00
Riley Bruins
3dfb9e6f60
feat(treesitter): include capture id in return value of get_captures_at_pos() #30559
**Problem:** Currently, it is difficult to get node(s)-level metadata
for a capture returned by `get_captures_at_pos()`. This is because it is
stored in `metadata[id]` and we do not have access to the value of `id`,
so to get this value we have to iterate over the keys of `metadata`. See
[this commit](d636229300 (diff-8bd4742121c2f359d0345f3c6c253a58220f1a28670cc4e1c957992232059a6cR16)).

Things would be much simpler if we were given the `id` of the capture so
we could use it to just index `metadata` directly.

**Solution:** Include `id` in the data returned by
`get_captures_at_pos()`
2024-12-11 04:34:24 -08:00
Colin Kennedy
492ae57aa6
docs(annotation): return types for Vimscript functions #31546 2024-12-11 03:27:08 -08:00
Lewis Russell
3f1d09bc94 feat(lsp): add vim.lsp.config and vim.lsp.enable
Design goals/requirements:
- Default configuration of a server can be distributed across multiple sources.
  - And via RTP discovery.
- Default configuration can be specified for all servers.
- Configuration _can_ be project specific.

Solution:

- Two new API's:
  - `vim.lsp.config(name, cfg)`:
    - Used to define default configurations for servers of name.
    - Can be used like a table or called as a function.
    - Use `vim.lsp.confg('*', cfg)` to specify default config for all
      servers.
  - `vim.lsp.enable(name)`
    - Used to enable servers of name. Uses configuration defined
    via `vim.lsp.config()`.
2024-12-10 17:16:01 +00:00
Tomasz N
ca760e645b
fix(messages): no message kind for :write messages #31519
- Problem: cannot replace the initial bufwrite message (from `filemess`) by the final one (`"test.lua" [New] 0L, 0B written`), when using `vim.ui_attach`.
- Solution: add kind to both messages.
2024-12-10 02:39:41 -08:00
bfredl
c87ca1e2eb
Merge pull request #30869 from vanaigr/decor_long_lines_perf
perf(decor): improve performance for long lines
2024-12-10 10:26:03 +01:00
Christian Clason
4182e98752 vim-patch:b66cac1: runtime(typst): add definition lists to formatlistpat, update maintainer
closes: vim/vim#16192

b66cac1a8e

Co-authored-by: Luca Saccarola <github.e41mv@aleeas.com>
2024-12-10 08:06:35 +01:00
Christian Clason
c3899419d4 vim-patch:ad4764f: runtime(proto): include filetype plugin for protobuf
closes: vim/vim#16199

ad4764f65b

Co-authored-by: David Pedersen <limero@me.com>
2024-12-10 08:06:35 +01:00
zeertzjq
d1fd674df3
fix(ui): update title in more cases (#31508) 2024-12-10 14:53:02 +08:00
zeertzjq
98694c3675
Merge pull request #31534 from zeertzjq/vim-9.0.2112
vim-patch: line shifting fixes
2024-12-10 14:50:27 +08:00
zeertzjq
e4bb185441 vim-patch:9.1.0917: various vartabstop and shiftround bugs when shifting lines
Problem:  various vartabstop and shiftround bugs when shifting lines
Solution: Fix the bugs, add new tests for shifting lines in various ways
          (Gary Johnson)

fixes: vim/vim#14891
closes: vim/vim#16193

eed63f96d2

Co-authored-by: Gary Johnson <garyjohn@spocom.com>
2024-12-10 14:29:24 +08:00
zeertzjq
6c81c16e1b vim-patch:9.0.2124: INT overflow detection logic can be simplified
Problem:  INT overflow logic can be simplified
Solution: introduce trim_to_int() function

closes: vim/vim#13556

2b0882fa65

vim-patch:9.0.2138: Overflow logic requires long long

Problem:  Overflow logic requires long long
Solution: Define vimlong_T data type to make life easier
          for porters

closes: vim/vim#13598

fda700cb04

Cherry-pick ops.c change from patch 9.1.0608.

Co-authored-by: Ernie Rael <errael@raelity.com>
2024-12-10 14:29:24 +08:00
zeertzjq
7a7ed0c8ac vim-patch:9.0.2122: [security]: prevent overflow in indenting
Problem:  [security]: prevent overflow in indenting
Solution: use long long and remove cast to (int)

The shiftwidth option values are defined as being long. However, when
calculating the actual amount of indent, we cast down to (int), which
may cause the shiftwidth value to become negative and later it may even
cause Vim to try to allocate a huge amount of memory.

We already use long and long long variable types to calculate the indent
(and detect possible overflows), so the cast to (int) seems superfluous
and can be safely removed. So let's just remove the (int) cast and
calculate the indent using longs.

Additionally, the 'shiftwidth' option value is also used when determining
the actual 'cino' options. There it can again cause another overflow, so
make sure it is safe in parse_cino() as well.

fixes: vim/vim#13554
closes: vim/vim#13555

3770574e4a

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-10 14:29:24 +08:00
zeertzjq
ac230370f3 vim-patch:9.0.2113: Coverity warns for another overflow in shift_line()
Problem:  Coverity warns for another overflow in shift_line()
Solution: Test for INT_MAX after the if condition, cast integer values
          to (long long) before multiplying.

22a97fc241

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-10 14:29:24 +08:00
zeertzjq
2336389d23 vim-patch:9.0.2112: [security]: overflow in shift_line
Problem:  [security]: overflow in shift_line
Solution: allow a max indent of INT_MAX

[security]: overflow in shift_line

When shifting lines in operator pending mode and using a very large
value, we may overflow the size of integer. Fix this by using a long
variable, testing if the result would be larger than INT_MAX and if so,
indent by INT_MAX value.

Special case: We cannot use long here, since on 32bit architectures (or
on Windows?), it typically cannot take larger values than a plain int,
so we have to use long long count, decide whether the resulting
multiplication of the shiftwidth value * amount is larger than INT_MAX
and if so, we will store INT_MAX as possible larges value in the long
long count variable.

Then we can safely cast it back to int when calling the functions to set
the indent (set_indent() or change_indent()). So this should be safe.

Add a test that when using a huge value in operator pending mode for
shifting, we will shift by INT_MAX

closes: vim/vim#13535

6bf131888a

Skip the test for now, as it takes too long and requires other fixes.

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-10 14:29:24 +08:00
luukvbaal
4889935a7a
docs(vvars): adjust lua types for vim.v variables #31510
- classes for v:event and v:completed_item
- add remaining unknown types
2024-12-09 16:27:39 -08:00
Eisuke Kawashima
1b90f4a9c4
build: mark CMake variables advanced #31412
The variables are not marked as advanced, thus they appear in e.g. `ccmake`.
2024-12-09 16:10:27 -08:00
Maria José Solano
3bb2d02759 docs: fix type of vim.validate value 2024-12-09 07:59:51 +00:00
zeertzjq
30726c778c
Merge pull request #31523 from zeertzjq/vim-eda923e
vim-patch: netrw fixes
2024-12-09 09:35:11 +08:00
zeertzjq
3d318be8cd vim-patch:92b3666: runtime(netrw): only check first arg of netrw_browsex_viewer for being executable
fixes: vim/vim#16185

92b36663f8

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-09 08:08:44 +08:00
zeertzjq
d7b3add63e vim-patch:eda923e: runtime(netrw): do not detach when launching external programs in gvim
On Debian 12 when detaching the program wouldn't launch at all

closes: vim/vim#16168

eda923e9c9

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
2024-12-09 08:07:06 +08:00
zeertzjq
84d9f4f9f9
vim-patch:9.1.0915: GVim: default font size a bit too small (#31516)
Problem:  GVim: default font size a bit too small
Solution: increase guifont size to 12 pt on GTK builds
          of gVim (matveyt).

fixes: vim/vim#16172
closes: vim/vim#16178

ad3b6a3340

Co-authored-by: matveyt <matthewtarasov@yandex.ru>
2024-12-08 20:29:25 +08:00
Lewis Russell
4bfdd1ee9d refactor(lsp): better tracking of requests
Not essential, but adds robustness and hardening for future
changes.
2024-12-08 10:10:29 +00:00
zeertzjq
ca4f688ad4
vim-patch:9.1.0913: no error check for neg values for 'messagesopt' (#31511)
Problem:  no error check for neg values for 'messagesopt'
          (after v9.1.0908)
Solution: add additional error checks and tests (h-east)

closes: vim/vim#16187

65be834c30

Nvim's getdigits() checks for overflow, so the code change isn't needed.

Co-authored-by: h-east <h.east.727@gmail.com>
2024-12-08 17:53:01 +08:00
zeertzjq
fe1e2eff06
fix(lua): avoid vim._with() double-free with cmdmod (#31505) 2024-12-08 09:25:43 +08:00
brianhuster
7008487b83 vim-patch:336fb22: translation(vi): Update Vietnamese translation
closes: vim/vim#16144

336fb22eae
2024-12-08 08:46:33 +08:00
zeertzjq
bf7e534c88 vim-patch:41afa30: runtime(doc): Add vietnamese.txt to helps main TOC
closes: vim/vim#16177

41afa308d6

Co-authored-by: h-east <h.east.727@gmail.com>
2024-12-08 08:46:33 +08:00
brianhuster
99a24d511f vim-patch:8a52587: runtime(doc): fix wrong syntax and style of vietnamese.txt
8a52587ee0

vim-patch:72212c9: runtime(doc): update wrong Vietnamese localization tag

72212c9bea

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-12-08 08:46:33 +08:00
brianhuster
5549115bee vim-patch:189e24b: runtime(doc): include vietnamese.txt
Since Vietnamese keymaps in Vim is quite differences from the
corresponding input methods, let's document the Vietnamese specifics in
vietnames.txt

related: vim/vim#16144

189e24bb14
2024-12-08 08:46:33 +08:00
zeertzjq
4fcc5cd34a
Merge pull request #31504 from zeertzjq/vim-9.1.0910
vim-patch:9.1.{0910,0911}: 'messagesopt' followup
2024-12-08 07:35:58 +08:00
zeertzjq
96329910b0 vim-patch:9.1.0911: Variable name for 'messagesopt' doesn't match short name
Problem:  Variable name for 'messagesopt' doesn't match short name
          (after v9.1.0908)
Solution: Change p_meo to p_mopt.  Add more details to docs.

closes: vim/vim#16182

8cc43daee1
2024-12-08 07:06:16 +08:00
zeertzjq
f3fa6507f2 vim-patch:9.1.0910: 'messagesopt' does not check max wait time
Problem:  'messagesopt' does not check max wait time
          (after v9.1.0908)
Solution: Check for max wait value
          (Shougo Matsushita)

closes: vim/vim#16183

d9e9f89e0f

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
2024-12-08 07:01:50 +08:00
Lewis Russell
668d2569b4 refactor: add vim._resolve_bufnr 2024-12-07 16:58:40 +00:00
Christian Clason
b52ffd0a59 fix(inspect): always show priority
Problem: It is not obvious if a treesitter highlight priority shown in
`:Inspect` is higher or lower than the default.

Solution: Also print default priority (`vim.hl.priorities.treesitter`).
Add padding for better readability.
2024-12-07 17:26:27 +01:00
zeertzjq
4817547ec4
feat(ex_cmds): :sleep! hides the cursor while sleeping (#31493)
Problem:  :sleep! not hiding the cursor is an arbitrary difference from
          Vim without obvious justification, and Vim's behavior isn't
          easily achievable in Nvim.
Solution: Make :sleep! hide the cursor while sleeping.

Ref:
6a01b3fcc3
b5c0ade437
2024-12-07 21:42:44 +08:00
bfredl
92e61072ac
Merge pull request #31475 from luukvbaal/delgravity
fix(marks): check gravity at range bounds when deleting text
2024-12-07 12:06:58 +01:00
Riley Bruins
c63e49cce2
fix(treesitter): #trim! range for nodes ending at col 0 #31488
Problem:
char-wise folding for `#trim!` ranges are improperly calculated for nodes that
end at column 0, due to the way `get_node_text` works.

Solution:
Add the blank line that `get_node_text` removes for for nodes ending at column
0. Also properly set column positions when performing linewise trims.
2024-12-07 03:01:59 -08:00
Lewis Russell
5c245ec3e9 fix: remove vim.lsp._with_extend
Not used anywhere.
2024-12-07 10:08:58 +00:00
tris203
bdfba8598b fix(lsp): cancel pending requests before refreshing
Problem:
Diagnostics and inlay hints can be expensive to calculate, and we
shouldn't stack them as this can cause noticeable lag.

Solution:
Check for duplicate inflight requests and cancel them before issuing a new one.
This ensures that only the latest request is processed, improving
performance and preventing potential conflicts.
2024-12-07 10:08:33 +00:00
Maria José Solano
c2bf09ddff fix(lsp): check for configuration workspace folders when reusing clients 2024-12-07 09:43:45 +00:00
Christian Clason
9c278af7cc fix(inspect): show priority for treesitter highlights
Problem: `:Inspect` does not show priority for treesitter highlights,
leading to confusion why sometimes earlier highlights override later
highlights.

Solution: Also print priority metadata if set.
2024-12-07 10:26:24 +01:00
zeertzjq
ec94c2704f
vim-patch:9.1.0908: not possible to configure :messages (#31492)
Problem:  not possible to configure :messages
Solution: add the 'messagesopt' option (Shougo Matsushita)

closes: vim/vim#16068

51d4d84d6a

Co-authored-by: Shougo Matsushita <Shougo.Matsu@gmail.com>
Co-authored-by: h_east <h.east.727@gmail.com>
2024-12-07 02:17:36 +00:00
Bartłomiej Maryńczak
517ecb85f5
feat(stdlib): vim.json.encode(...,{escape_slash:boolean}) #30561
Problem:
vim.json.encode escapes every slash in string values (for example in
file paths), and is not optional. Use-case is for preventing HTML
injections (eg. injecting `</script>` closing tag); in the context of
Nvim this is rarely useful.

Solution:
- Add a `escape_slash` flag to `vim.json.encode`.
- Defaults to `false`. (This is a "breaking" change, but more like
  a bug fix.)
2024-12-06 12:43:41 -08:00
Tristan Knight
fac96b72a5
fix(lsp): add foldingrange method support check #31463
Problem: The folding_range request method assumes that the client
supports the method

Solution: Add a capability guard to the call
2024-12-06 10:09:07 -08:00
Gregory Anders
2550b5e9bd
docs: do not escape Lua keywords #31467 2024-12-06 10:08:46 -08:00
Justin M. Keyes
ba7370a902
Merge #30085 #trim! all whitespace 2024-12-06 10:08:20 -08:00
Riley Bruins
f0ea38a4bc test(treesitter): add a simple testutil file
The util file, for now, just abstracts the common `run_query` function.
2024-12-06 08:36:28 -08:00
Riley Bruins
b8c75a31e6 feat(treesitter): #trim! can trim all whitespace
This commit also implements more generic trimming, acting on all
whitespace (charwise) rather than just empty lines.

It will unblock
https://github.com/nvim-treesitter/nvim-treesitter/pull/3442 and allow
for properly concealing markdown bullet markers regardless of indent
width, e.g.
2024-12-06 08:36:08 -08:00
Micah Halter
e8e3b443f8
feat(defaults): disable 'foldcolumn' in terminal buffers (#31480) 2024-12-06 10:19:24 -06:00
zeertzjq
1077843b9b
fix(filetype): make filetype detection work with :doautocmd (#31470) 2024-12-06 20:57:21 +08:00
Brian A. Weston
367182abd5
docs: delineate blocks/list items #30973
Problem: Paragraph below bulleted list was joined to last list item instead of dropping below as expected. Same with "Notes:" paragraph below it.

Solution: Added necessary newlines.
2024-12-06 04:48:50 -08:00
luukvbaal
e788d1a3a9
fix(completion): avoid deleting text when completion leader changes #31448
Problem:  When completion leader changes, text that might be reinserted
          immediately after is deleted. This unnecessarily affects
          extmarks. #31387 restored the original extmarks but that
          prevents end_right_gravity marks from growing.
Solution: Avoid deleting leader text that will be reinserted.
2024-12-06 04:07:52 -08:00
zeertzjq
e9f4ceeb74
fix(events): don't expand args.file for Lua callback (#31473)
Problem:  In an autocommand Lua callback whether `args.file` is expanded
          depends on whether `expand('<afile>')` has been called.
Solution: Always use the unexpanded file name for `args.file`.

Related to #31306 and vim/vim#16106. This doesn't provide `sfname`, but
at least makes `args.file` have a consistent value.
2024-12-06 20:01:28 +08:00
Luuk van Baal
c4f76299f0 fix(marks): skip right_gravity marks when deleting text
Problem:  Marks that are properly restored by the splice associated with
          an undo edit, are unnecessarily pushed to the undo header. This
          results in incorrect mark tracking in the "copy_only"
          save/restore completion path.
Solution: Avoid pushing left gravity marks at the beginning of the range,
          and right gravity marks at the end of the range to the undo
          header.
2024-12-06 11:57:07 +01:00
Christian Clason
812d029702 vim-patch:9.1.0906: filetype: Nvidia PTX files are not recognized
Problem:  filetype: Nvidia PTX files are not recognized
Solution: detect '*.ptx' files as ptx filetype (Yinzuo Jiang)

Reference: https://docs.nvidia.com/cuda/parallel-thread-execution/

closes: vim/vim#16171

bdb5f85a51

Co-authored-by: Yinzuo Jiang <jiangyinzuo@foxmail.com>
2024-12-06 09:40:44 +01:00
zeertzjq
bf5c1346c5
vim-patch:ea0e41a: runtime(doc): make tag alignment more consistent in filetype.txt (#31459)
closes: vim/vim#16169

ea0e41a115

Omit Lua folding.

N/A patch:
vim-patch:fdfcce5: runtime(lua): add optional lua function folding
2024-12-06 07:22:44 +08:00
Jeremy Fleischman
fd902b1cb2
fix(diagnostic): only store quickfix id when creating a new one #31466
The old code would always update `_qf_id` with the current quickfix,
even if you're currently looking at a completely different,
non-diagnostics quickfix list. This completely defeats the intent of
<https://github.com/neovim/neovim/pull/30868>, whoops!
2024-12-05 13:59:33 -08:00
Justin M. Keyes
12901447cb
docs: graduate intro.txt to "flow layout" #31462
- move credits and backers to credits.txt
2024-12-05 07:18:27 -08:00
vanaigr
fccef5ec35 refactor: comments, variable names 2024-12-05 08:45:22 -06:00
vanaigr
c57397f981 docs: add comments for DecorRangeSlot struct 2024-12-05 08:45:22 -06:00
vanaigr
3abd7ed4a4 perf: consider only active decorations when drawing lines 2024-12-05 08:45:22 -06:00
Justin M. Keyes
845e563421
Merge #31451 docs 2024-12-05 04:02:34 -08:00
zeertzjq
8323398bc6
fix(defaults): don't replace keycodes in Visual search mappings (#31460)
Also remove "silent" to be more consistent with Normal mode search.
2024-12-05 19:03:58 +08:00
glepnir
6a929b15c9
vim-patch:9.1.0903: potential overflow in spell_soundfold_wsal() (#31456)
Problem:  potential overflow in spell_soundfold_wsal()
Solution: Protect wres from buffer overflow, by checking the
          length (Zdenek Dohnal)

Error: OVERRUN (CWE-119):
vim91/src/spell.c:3819: cond_const: Checking "reslen < 254" implies that
"reslen" is 254 on the false branch.
vim91/src/spell.c:3833: incr: Incrementing "reslen". The value of "reslen"
is now 255.
vim91/src/spell.c:3792: overrun-local: Overrunning array "wres" of 254
4-byte elements at element index 254 (byte offset 1019) using index
"reslen - 1" (which evaluates to 254).
 3789|   		    {
 3790|   			// rule with '<' is used
 3791|-> 			if (reslen > 0 && ws != NULL && *ws != NUL
 3792|   				&& (wres[reslen - 1] == c
 3793|   						    || wres[reslen - 1] == *ws))

Error: OVERRUN (CWE-119):
vim91/src/spell.c:3819: cond_const: Checking "reslen < 254" implies that
"reslen" is 254 on the false branch.
vim91/src/spell.c:3833: overrun-local: Overrunning array "wres" of 254
4-byte elements at element index 254 (byte offset 1019) using index
"reslen++" (which evaluates to 254).
 3831|                         {
 3832|                             if (c != NUL)
 3833|->                               wres[reslen++] = c;
 3834|                             mch_memmove(word, word + i + 1,
 3835|                                        sizeof(int) * (wordlen -
(i + 1) + 1));

related: vim/vim#16163

39a94d2048

Co-authored-by: Zdenek Dohnal <zdohnal@redhat.com>
2024-12-05 09:51:58 +00:00
glepnir
2f5e7cbac4
vim-patch:9.1.0905: Missing information in CompleteDone event (#31455)
Problem:  Missing information in CompleteDone event
Solution: add complete_word and complete_type to v:event dict
          (glepnir)

closes: vim/vim#16153

1c5a120a70
2024-12-05 17:49:39 +08:00
zeertzjq
540def7d2c
test(system_spec): check for .git dir before using git (#31458) 2024-12-05 09:13:22 +00:00
Justin M. Keyes
5413c6475e docs: graduate gui.txt to "flow layout" 2024-12-05 01:38:44 +01:00
Lewis Russell
8f84167c30 refactor(runtime.c): misc 2024-12-04 16:26:04 +00:00
Gregory Anders
0a15cd2500
misc: keep deprecated vim.loader.disable stub (#31450)
Transitional stub to minimize breaking change pain, to be removed after
0.11 release.
2024-12-04 10:17:46 -06:00
Gregory Anders
52481eecf0
docs: mention new terminal defaults (#31449) 2024-12-04 10:17:19 -06:00
Jeremy Fleischman
7579af3c51
feat(diagnostic): vim.diagnostic.setqflist improvements #30868
1. Use the new "u" action to update the quickfix list so we don't lose
   our position in the quickfix list when updating it.
2. Rather than creating a new quickfix list each time, update the
   exiting one if we've already created one.
2024-12-04 07:49:57 -08:00
Justin M. Keyes
6586645d78 docs: help tags for neovim.io searches 2024-12-04 16:34:44 +01:00
luukvbaal
e2a91876ac
test(screen): adjust screen state per stylua #31441
Before:
screen:expect({        | screen:expect({
  grid = [[            |   grid = [[
    {10:>!}a        |  |     line ^1                   |
    {7:  }b        |   |     {1:~                        }|*4
    {10:>>}c        |  |   ]], messages={ {
    {7:  }^         |  |     content = { { "\ntest\n[O]k: ", 6, 11 } },
    {1:~          }|*9 |     kind = "confirm"
               |       |   } }
  ]]                   | })
})

After:
screen:expect([[         | screen:expect({
  {10:>!}a            |  |   grid = [[
  {7:  }b            |   |     line ^1                   |
  {10:>>}c            |  |     {1:~                        }|*4
  {7:  }^             |  |   ]],
  {1:~              }|*9 |   messages = { {
                 |       |     content = { { "\ntest\n[O]k: ", 6, 11 } },
]])                      |     kind = "confirm"
                         |   } },
                         | })
2024-12-04 07:31:08 -08:00
Justin M. Keyes
6551e30630
Merge #31358 fix test failures for release / tarball builds 2024-12-04 07:20:04 -08:00
Lewis Russell
734dba04d1 fix(vim.system): close pipe handles after process handle
Fixes #30846
2024-12-04 14:44:40 +00:00
Gregory Anders
56d11b494b
defaults: disable 'number', 'relativenumber', and 'signcolumn' in terminal buffers (#31443) 2024-12-04 08:40:01 -06:00
luukvbaal
3cb1e825e6
fix(column): check if signcolumn changed in all windows #31439 2024-12-04 05:20:24 -08:00
Maria José Solano
e56437cd48
feat(lsp): deprecate vim.lsp.start_client #31341
Problem:
LSP module has multiple "start" interfaces.

Solution:
- Enhance vim.lsp.start
- Deprecate vim.lsp.start_client
2024-12-04 05:14:47 -08:00
zeertzjq
b079a9d2e7
vim-patch:9.1.0902: filetype: Conda configuration files are not recognized (#31445)
Problem:  filetype: Conda configuration files are not recognized
Solution: detect '.condarc' and 'condarc' files as yaml filetype.
          (zeertzjq)

closes: vim/vim#16162

876de275cb
2024-12-04 17:49:12 +08:00
Justin M. Keyes
ae93c7f369
docs: misc, help tags for neovim.io searches #31428
Problem:
Various keywords are commonly searched-for on https://neovim.io, but
don't have help tags.

Solution:
Add help tags.

fix #31327
2024-12-03 09:44:28 -08:00
wzy
2495e7e22a
fix(clipboard): tmux clipboard depends on $TMUX #31268
Problem:
tmux clipboard not used when tmux is a daemon and $TMUX is empty.

Solution:
If `tmux list-buffers` succeeds, use tmux clipboard.
2024-12-03 05:06:54 -08:00
JD
0e299ebf75
fix(decorator): noisy errors from decoration provider #31418
Problem:
A broken decoration provider can cause endless errors. #27235

Solution:
Don't show decorator errors when they exceed `DP_MAX_ERROR`.
2024-12-03 03:41:37 -08:00
James McCoy
48bdbf12d0
test(marktree): expose test functions in release builds
In order to run the marktree unit test in release mode, the test functions need to be available even when NDEBUG is defined.

Keep the body of marktree_check a nop during release builds, which limits the usefulness of the testing, but at least lets the tests run.
2024-12-03 06:34:07 -05:00
James McCoy
c410375d4d
ci: run tests directly rather than via the Makefile
Since the Makefile is not used to build, running the tests via the Makefile causes cmake to reconfigure and revert the release build back to debug.
2024-12-03 06:31:09 -05:00
James McCoy
9123bc0f3f
test(main_spec): make "nvim -v" test agnostic to build type
In release builds, the Compilation: line is omitted so the build is reproducible. Since the "fall-back for $VIM" line is always present, check for that instead.
2024-12-03 06:31:09 -05:00
James McCoy
25bd2782a5
test(version_spec): expect vim.NIL, not nil, for "build" if not in a git clone 2024-12-03 06:31:09 -05:00
James McCoy
e5d96a69fd
test(main_spec): use CMakePresets.json instead of .git for root marker 2024-12-03 06:31:09 -05:00
James McCoy
05dd41f3e9
ci(test): remove the .git directory for Linux
Tests should not rely on being run inside a git clone, so the Linux
builds cover this use case. The macOS builds will continue running with
the .git directory so there's still unix-ish coverage within a git
clone.
2024-12-03 06:31:09 -05:00
James McCoy
747e84a256
ci: run one set of tests with a release build
This ensures that no tests fail due to differences between release and debug builds.

The release build-type check is now unnecessary, too, so remove it.
2024-12-03 06:31:01 -05:00
James McCoy
588ca99e12
Merge pull request #31408 from jamessan/vterm-test-fixture
test(vterm): move test functions into vterm_test fixture
2024-12-03 04:30:42 -07:00
James McCoy
7a367c6967
test(vterm): move test functions into vterm_test fixture
In order to run unittests with a release build, we need the test
functions to be accessible when NDEBUG is defined. Moving the functions
into the test fixture ensures they are available and only available for
use by the unit tests.
2024-12-02 21:49:14 -05:00
zeertzjq
3d3a99e69c
vim-patch:9.1.0900: Vim9: digraph_getlist() does not accept bool arg (#31431)
Problem:  Vim9: digraph_getlist() does not accept bool argument
          (Maxim Kim)
Solution: accept boolean as first argument (Yegappan Lakshmanan)

fixes: vim/vim#16154
closes: vim/vim#16159

198ada3d9f

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2024-12-03 00:32:23 +00:00
Gregory Anders
49d6cd1da8
docs: provide example for configuring LSP foldexpr (#31411)
Using the "supports_method" function with a client capability inside of
an LspAttach autocommand is the preferred method to do this, so we
should be showing users how to do it.
2024-12-02 12:13:09 -06:00
luukvbaal
c7ec010ade
fix(extmark): builtin completion can still affect nearby extmarks #31387
Problem:
Built-in completion can still affect nearby extmarks. #31384

Solution:
Restore extmarks when completion leader changes.
2024-12-02 06:11:38 -08:00
luukvbaal
9d0117fd30
test(treesitter): global highlight definitions and fold test #31407
Add test for foldtext= highlighting. Change file to global highlight
definitions while at it.
2024-12-02 06:08:26 -08:00
Justin M. Keyes
716adbcc45
fix(api): deprecate nvim_subscribe, nvim_unsubscribe #30456
Problem:
- nvim_subscribe, nvim_unsubscribe were deprecated in
  aec4938a21 but this wasn't set in the
  API metadata.
- The function annotations
  ```
  FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY FUNC_API_DEPRECATED_SINCE(13)
  ```
  cause this test to fail:
   ```
   RUN T3 api metadata functions are compatible with old metadata or have new level: 3.00 ms ERR
   test/functional/api/version_spec.lua:135: function vim_subscribe was removed but exists in level 0 which nvim should be compatible with
   stack traceback:
     test/functional/api/version_spec.lua:135: in function <test/functional/api/version_spec.lua:128>
   ```

Solution:
- Set the API metadata.
- Rearrange the annotations so that FUNC_API_DEPRECATED_SINCE is 2nd:
  ```
  FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) FUNC_API_REMOTE_ONLY
  ```
2024-12-02 04:16:44 -08:00
dundargoc
c1378413c1 vim-patch:768728b: runtime(doc): Update documentation for "noselect" in 'completeopt'
In particular, make the distinction and interaction between "noinsert"
and "noselect" clearer as it was very confusing before.

closes: vim/vim#16148

768728b487

Co-authored-by: dundargoc <gocdundar@gmail.com>
2024-12-02 08:23:10 +01:00
Christian Clason
36b714e9b7 vim-patch:9a39483: runtime(typst): provide a formatlistpat in ftplugin
closes: vim/vim#16134

9a39483adb

Co-authored-by: Luca Saccarola <github.e41mv@aleeas.com>
2024-12-02 08:19:50 +01:00
zeertzjq
6cdcac4492
fix(ui): clamp 'cmdheight' for other tabpages on screen resize (#31419) 2024-12-02 10:05:49 +08:00
Evgeni Chasnovski
8de1dc6923
fix(api): make nvim_set_hl() respect all cterm attributes (#31390) 2024-12-02 08:24:58 +08:00
zeertzjq
fb689d7ebd
vim-patch:9.1.0899: default for 'backspace' can be set in C code (#31416)
Problem:  default for 'backspace' can be set in C code
Solution: promote the default for 'backspace' from defaults.vim to the C
          code (Luca Saccarola)

closes: vim/vim#16143

959ef61430

N/A patches:
vim-patch:9.1.0895: default history value is too small
vim-patch:075aeea: runtime(doc): document changed default value for 'history'

Co-authored-by: Luca Saccarola <github.e41mv@aleeas.com>
2024-12-02 00:06:57 +00:00
C.D. MacEachern
feb62d5429
docs: example keybind for :Inspect #31391 2024-12-01 13:58:28 -08:00
zeertzjq
ab9cfc4dc3
Merge pull request #31370 from glepnir/vim-9.1.0867
vim-patch:9.1.{0867,0891,0896}
2024-11-30 20:46:46 +08:00
Christian Clason
9d174a7dac vim-patch:9.1.0898: runtime(compiler): pytest compiler not included
Problem:  runtime(compiler): pytest compiler not included
Solution: include pytest compiler, update the compiler completion test
          (Konfekt)

closes: vim/vim#16130

3c2596a9e9

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
2024-11-30 13:40:08 +01:00
glepnir
1af1e918d3 vim-patch:9.1.0896: completion list wrong after v9.1.0891
Problem:  completion list wrong after v9.1.0891
Solution: update compl_mach_array after leader change
          (glepnir)

compl_shown_match update not correct after refactoring in v9.1.0891
Unfortunately, this regressed what item is selected after leader change.

So generate compl_match_array before updating compl_shown_match range,
and split generate compl_match_array into range match_head

fixes: https://github.com/vim/vim/issues/16128
closes: https://github.com/vim/vim/pull/16129

a49c077a88
2024-11-30 20:22:53 +08:00
glepnir
d512479115 vim-patch:9.1.0891: building the completion list array is inefficient
Problem:  building the completion list array is inefficient
Solution: refactor and improve ins_compl_build_pum() func
          (glepnir)

current time complexity is O(n^2). I guess garray is not used here to save memory and avoid efficiency
is caused by heap memory allocation. A simple way is to add an extra pointer as a single linked list
to store the matching compl_T, and traverse this single linked list to generate compl_match_array.
The time complexity is O(n x m). The worst case is m=n, but we can still get a little improvement.
Because the if condition does not need to be run at one time. This should be a good solution for now.
Later we may be able to complete it in O(lgn) time. But this requires more reconstruction. So this is
the first step.

closes: #16125

80b662009c
2024-11-30 18:53:29 +08:00
Christian Clason
4426a326e2 vim-patch:9.1.0897: filetype: pyrex files are not detected
Problem:  filetype: pyrex files are not detected
Solution: detect '*.pxi' and '*.pyx+' as pyrex filetype
          (user202729)

References:
https://cython.readthedocs.io/en/latest/src/userguide/language_basics.html#cython-file-types
https://www.csse.canterbury.ac.nz/greg.ewing/python/Pyrex/version/Doc/Manual/using_with_c++.html

closes: vim/vim#16136

aa16b30552

Co-authored-by: user202729 <25191436+user202729@users.noreply.github.com>
2024-11-30 11:41:23 +01:00
Christian Clason
fd865fbd92 vim-patch:dd21c89: runtime(compiler): update eslint compiler
compact formatter is no longer distributed with eslint, so:

- switch to '--format stylish' in makeprg
- update 'errorformat' for the 'stylish' format output

fixes: vim/vim#16126
closes: vim/vim#16137

dd21c89626

Co-authored-by: Romain Lafourcade <romainlafourcade@gmail.com>
2024-11-30 11:39:36 +01:00
Yochem van Rosmalen
2833925cfc
docs(diagnostics): location list / quickfix example #31371 2024-11-29 10:07:08 -08:00
Lewis Russell
3056115785 refactor: gen_declarations.lua
Problem:
gen_declarations.lua is complex and has duplicate logic with
c_grammar.lua

Solution:
Move all lpeg logic to c_grammar.lua and refactor gen_declarations.lua.
2024-11-29 13:25:53 +00:00
Yi Ming
a1e313ded6
feat(lsp): support textDocument/foldingRange (#31311)
* refactor(shared): extract `vim._list_insert` and `vim._list_remove`

* feat(lsp): add `vim.lsp.foldexpr()`

* docs(lsp): add a todo for state management

* feat(lsp): add `vim.lsp.folding_range.foldclose()`

* feat(lsp): schedule `foldclose()` if the buffer is not up-to-date

* feat(lsp): add `vim.lsp.foldtext()`

* feat(lsp): support multiple folding range providers

* refactor(lsp): expose all folding related functions under `vim.lsp.*`

* perf(lsp): add `lsp.MultiHandler` for do `foldupdate()` only once
2024-11-29 12:40:32 +00:00
Christian Clason
c867a4f5e3 build(deps): bump luajit to HEAD - 19878ec05 2024-11-29 09:08:52 +01:00
Christian Clason
e74316bf48 vim-patch:511eb84: runtime(po): remove poDiffOld/New, add po-format flags to syntax file
fixes: vim/vim#16120
closes: vim/vim#16132

511eb84c08

Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
2024-11-29 08:10:51 +01:00
zeertzjq
b1c907f219
vim-patch:9.1.0892: the max value of 'cmdheight' is limited by other tabpages (#31378)
Problem:  the max value of 'cmdheight' is limited by other tabpages
Solution: Limit the maximum value of 'cmdheight' to the current tabpage only.
          (Milly)

The Help says that cmdheight is local to the tab page, but says nothing
about the maximum value depending on the state of all tab pages. Users
may wonder why they can't increase cmdheight when there are still rows
available on the current tab page. This PR changes the behavior of
cmdheight so that its maximum value depends only on the state of the
current tab page.

Also, since magic numbers were embedded in various places with the
minimum value of cmdheight being 1, we defined a constant to make it
easier to understand.

closes: vim/vim#16131

2cddf0e85a

Cherry-pick Test_cmdheight_not_changed() from patch 9.0.0187.

Co-authored-by: Milly <milly.ca@gmail.com>
2024-11-29 10:12:30 +08:00
zeertzjq
1536f79d86
vim-patch:8.2.2993: 'fileencodings' default value should depend on 'encoding' (#31379)
Problem:    'fileencodings' default value should depend on 'encoding'. (Gary
            Johnson)
Solution:   When 'encoding' is "utf-8" use a different default value for
            'fileencodings'.

5ffefbb35a

Co-authored-by: Bram Moolenaar <Bram@vim.org>
2024-11-29 02:06:12 +00:00
zeertzjq
27965627a4
Merge pull request #31377 from zeertzjq/vim-65311c6
vim-patch: :compiler spotbugs
2024-11-29 09:19:51 +08:00
zeertzjq
cfa8418c21 vim-patch:9.1.0894: No test for what the spotbug compiler parses
Problem:  No test for what the spotbug compiler parses
          (after commit: 65311c6f472de67b368)
Solution: Test &makeprg for the SpotBugs compiler plugin
          (Aliaksei Budavei)

closes: vim/vim#16096

60ddb1a140

Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
2024-11-29 08:58:47 +08:00
zeertzjq
8d7d225caa vim-patch:65311c6: runtime(compiler): include spotbugs Java linter
closes: vim/vim#16001

65311c6f47

Co-authored-by: Konfekt <Konfekt@users.noreply.github.com>
Co-authored-by: Aliaksei Budavei <0x000c70@gmail.com>
2024-11-29 08:57:00 +08:00
vanaigr
731f83ea4a test: add decor benchmarks 2024-11-28 14:11:52 -06:00
Yi Ming
146b8300a1
docs(lsp): update example, optional parameters #31299 2024-11-28 08:08:27 -08:00
Riley Bruins
864f25d6b0 docs: more accurate typing for LSP references context
**Problem:** The `context` parameter for `references()` is just typed as
a table, which is unhelpful.

**Solution:** Properly type it as an `lsp.ReferenceContext`!
2024-11-28 09:05:17 +01:00
glepnir
344923fe9a vim-patch:9.1.0867: ins_compl_add() has too many args
Problem:  ins_compl_add() has too many args
Solution: refactor it and use an int array instead of 2 separate int
          args (glepnir)

closes: vim/vim#16062

5c66e23c62

Co-authored-by: glepnir <glephunter@gmail.com>
2024-11-28 13:58:42 +08:00
zeertzjq
5897994cb7
vim-patch:9.1.0890: %! item not allowed for 'rulerformat' (#31369)
Problem:  %! item not allowed for 'rulerformat'
          (yatinlala)
Solution: also allow to use %! for rulerformat option
          (Yegappan Lakshmanan)

fixes: vim/vim#16091
closes: vim/vim#16118

ac023e8baa

Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2024-11-28 09:02:10 +08:00
dundargoc
76dcc7029b docs: add tag vim.fs.exists() and document suggested replacement 2024-11-27 19:56:08 +01:00
glepnir
203e7a43d1
fix(lsp): mention function name in warning #31301
Problem: The warning message is the same in different functions.
It is not convenient to locate the specific function name

Solution: add function name in warning message
2024-11-27 05:44:29 -08:00
Mathias Fussenegger
c24e6e66dd ci: remove myself from lsp reviewers 2024-11-27 13:16:06 +01:00
Christian Clason
078e8e57d3 vim-patch:7e501f4: runtime(gzip): load undofile if there exists one
fixes: vim/vim#16102
closes: vim/vim#16122

7e501f4d99

Co-authored-by: Christian Brabandt <cb@256bit.org>
2024-11-27 08:45:22 +01:00
Gregory Anders
d460928263
feat(tui): update 'background' on theme change events (#31350)
Enabling private DEC mode 2031 tells the terminal to notify Nvim
whenever the OS theme changes (i.e. light mode to dark mode or vice
versa) or the terminal emulator's palette changes. When we receive one
of these notifications we query the terminal color's background color
again to see if it has changed and update the value of 'background' if
it has.

We only do this though if the user has not explicitly set the value of
'bg' themselves. The help text is updated slightly to hint to users that
they probably shouldn't set this value: on modern terminal emulators
Nvim is able to completely determine this automatically.
2024-11-26 14:22:01 -06:00
Gregory Anders
99b5ffd688
perf(vim.text): use lookup table implementation for hex encoding (#30080)
Co-authored-by: glepnir <glephunter@gmail.com>
2024-11-26 13:56:01 -06:00
zeertzjq
e8450ef236
vim-patch:9.1.0889: Possible unnecessary redraw after adding/deleting lines (#31356)
Problem:  Possible unnecessary redraw after adding/deleting lines.
Solution: Check b_mod_set before using b_mod_xlines to avoid using stale
          b_mod_xlines value (zeertzjq).

closes: vim/vim#16124

9f25a3a237
2024-11-26 14:55:05 +00:00
Justin M. Keyes
3d707e6f14
fix(lua): remove vim.loader.disable() #31344
Problem:
`vim.loader.disable` does not conform to `:help dev-name-common` and
`:help dev-patterns`.

Solution:
- Add `enable` parameter to `vim.loader.enable`
- Remove `vim.loader.disable`
- Note the change in `:help news-breaking-dev` (HEAD changes).
  - This is not a breaking change (except to "HEAD") because
    `vim.loader` is marked "experimental".

previous: 26765e8461
2024-11-26 06:15:50 -08:00
zeertzjq
66bb1e577c
vim-patch:9.1.0888: leftcol property not available in getwininfo() (#31349)
Problem:  leftcol property not available in getwininfo()
Solution: add leftcol property property (glepnir)

closes: vim/vim#16119

0a850673e3

Co-authored-by: glepnir <glephunter@gmail.com>
2024-11-26 07:53:07 +08:00
Marcus Caisey
c644228e1d
fix(defaults): omit empty line from unimpaired mapping messages (#31347)
Problem:
The default unimpaired mappings display an empty line after the
command's output. This results (with default configuration) in the
`Press ENTER or type command to continue` prompt to be displayed, like
so:
```
(2 of 16): item2

Press ENTER or type command to continue
```

Solution:
The cause is that we're checking the second return value from
`pcall(vim.api.nvim_cmd, opts, {})` to determine whether the call was
successful. `nvim_cmd` returns an empty string on success, so this value
is an empty string in the successful path which we then display.

The fix is simple: check the first return value instead which is the
"status code" of the call.
2024-11-25 16:33:11 -06:00
Gregory Anders
f81131cca2
fix(tui): also reset cursor color if it was invisible (#31348) 2024-11-25 16:32:03 -06:00
Gregory Anders
29c72cdf4a
fix(lsp): retrigger diagnostics request on server cancellation (#31345)
Co-authored-by: Jesse <github@jessebakker.com>
2024-11-25 11:48:11 -06:00
Lewis Russell
8d55cc218c feat(keysets): teach Union and LuaRefOf 2024-11-25 17:34:02 +00:00
Mathias Fußenegger
99e7323aa3
feat(diagnostic): inherit parent 'path' option in open_float (#31273)
Diagnostics sometimes contain stack traces, it's useful being able to
use `CTRL-W F` on them to open related files from within the diagnostic
window.
2024-11-25 17:11:22 +01:00
Yi Ming
165b099fa3
refactor(lsp): rename offset_encoding to position_encoding #31286
Problem:
LSP spec uses the term "position encoding" where we say "offset encoding".

Solution:
- Rename it everywhere except `vim.lsp.Client.offset_encoding` (which would be breaking).
- Mention "position encoding" in the documentation for `vim.lsp.Client.offset_encoding`.
2024-11-25 08:06:05 -08:00
Gregory Anders
a811d4babd
fix(tui): only reset cursor color if it was changed (#31337)
We already track this information so we might as well use it. This
eliminates a bunch of unnecessary OSC sequences.
2024-11-25 15:00:42 +00:00
295 changed files with 16517 additions and 11895 deletions

View File

@ -57,7 +57,6 @@ module.exports = async ({ github, context }) => {
if (labels.includes("lsp")) {
reviewers.add("MariaSolOs");
reviewers.add("mfussenegger");
}
if (labels.includes("netrw")) {

View File

@ -89,7 +89,9 @@ jobs:
for d in *; do (cd "$d"; rm -rf ./autom4te.cache; make clean || true; make distclean || true); done
- name: Re-build bundled dependencies with no network access
run: unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
unshare --map-root-user --net make deps DEPS_CMAKE_FLAGS=-DUSE_EXISTING_SRC_DIR=ON
- name: Build
run: make CMAKE_FLAGS="-D CI_BUILD=ON"

View File

@ -106,7 +106,7 @@ jobs:
[
{ runner: ubuntu-24.04, os: ubuntu, flavor: asan, cc: clang, flags: -D ENABLE_ASAN_UBSAN=ON },
{ runner: ubuntu-24.04, os: ubuntu, flavor: tsan, cc: clang, flags: -D ENABLE_TSAN=ON },
{ runner: ubuntu-24.04, os: ubuntu, cc: gcc },
{ runner: ubuntu-24.04, os: ubuntu, flavor: release, cc: gcc, flags: -D CMAKE_BUILD_TYPE=Release },
{ runner: macos-13, os: macos, flavor: intel, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
{ runner: macos-15, os: macos, flavor: arm, cc: clang, flags: -D CMAKE_FIND_FRAMEWORK=NEVER, deps_flags: -D CMAKE_FIND_FRAMEWORK=NEVER },
{ runner: ubuntu-24.04, os: ubuntu, flavor: puc-lua, cc: gcc, deps_flags: -D USE_BUNDLED_LUAJIT=OFF -D USE_BUNDLED_LUA=ON, flags: -D PREFER_LUA=ON },
@ -145,6 +145,10 @@ jobs:
sudo cpanm -n Neovim::Ext || cat "$HOME/.cpanm/build.log"
perl -W -e 'use Neovim::Ext; print $Neovim::Ext::VERSION'
- name: Remove .git directory
if: ${{ matrix.build.os == 'ubuntu' }}
run: cmake -E rm -rf -- .git
- name: Build third-party deps
run: |
cmake -S cmake.deps --preset ci -D CMAKE_BUILD_TYPE=Debug ${{ matrix.build.deps_flags }}
@ -155,9 +159,15 @@ jobs:
cmake --preset ci -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX:PATH=$INSTALL_PREFIX ${{ matrix.build.flags }}
cmake --build build
- name: ${{ matrix.test }}
- if: ${{ matrix.test == 'oldtest' }}
name: ${{ matrix.test }}
timeout-minutes: 20
run: make ${{ matrix.test }}
run: make -C test/old/testdir NVIM_PRG=$(realpath build)/bin/nvim
- if: ${{ matrix.test != 'oldtest' }}
name: ${{ matrix.test }}
timeout-minutes: 20
run: cmake --build build --target ${{ matrix.test }}
- name: Install
run: |
@ -194,7 +204,7 @@ jobs:
uses: ./.github/workflows/test_windows.yml
# This job tests the following things:
# - Check if Release, MinSizeRel and RelWithDebInfo compiles correctly.
# - Check if MinSizeRel and RelWithDebInfo compiles correctly.
# - Test the above build types with the GCC compiler specifically.
# Empirically the difference in warning levels between GCC and other
# compilers is particularly big.
@ -218,9 +228,6 @@ jobs:
- name: Configure
run: cmake --preset ci -G "Ninja Multi-Config"
- name: Release
run: cmake --build build --config Release
- name: RelWithDebInfo
run: cmake --build build --config RelWithDebInfo

View File

@ -187,6 +187,7 @@ if(NOT PREFER_LUA)
find_program(LUA_PRG NAMES luajit)
endif()
find_program(LUA_PRG NAMES lua5.1 lua5.2 lua)
mark_as_advanced(LUA_PRG)
if(NOT LUA_PRG)
message(FATAL_ERROR "Failed to find a Lua 5.1-compatible interpreter")
endif()
@ -200,6 +201,7 @@ message(STATUS "Using Lua interpreter: ${LUA_PRG}")
if(NOT LUA_GEN_PRG)
set(LUA_GEN_PRG "${LUA_PRG}" CACHE FILEPATH "Path to the lua used for code generation.")
endif()
mark_as_advanced(LUA_GEN_PRG)
message(STATUS "Using Lua interpreter for code generation: ${LUA_GEN_PRG}")
option(COMPILE_LUA "Pre-compile Lua sources into bytecode (for sources that are included in the binary)" ON)
@ -219,6 +221,7 @@ if(COMPILE_LUA AND NOT WIN32)
endif()
endif()
endif()
mark_as_advanced(LUAC_PRG)
if(LUAC_PRG)
message(STATUS "Using Lua compiler: ${LUAC_PRG}")
endif()
@ -229,7 +232,9 @@ if(CI_LINT)
set(LINT_REQUIRED "REQUIRED")
endif()
find_program(SHELLCHECK_PRG shellcheck ${LINT_REQUIRED})
mark_as_advanced(SHELLCHECK_PRG)
find_program(STYLUA_PRG stylua ${LINT_REQUIRED})
mark_as_advanced(STYLUA_PRG)
set(STYLUA_DIRS runtime scripts src test contrib)

View File

@ -1,8 +1,8 @@
LIBUV_URL https://github.com/libuv/libuv/archive/v1.49.2.tar.gz
LIBUV_SHA256 388ffcf3370d4cf7c4b3a3205504eea06c4be5f9e80d2ab32d19f8235accc1cf
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/fe71d0fb54ceadfb5b5f3b6baf29e486d97f6059.tar.gz
LUAJIT_SHA256 92325f209b21aaf0a67b099bc73cf9bbac5789a9749bdc3898d4a990abb4f36e
LUAJIT_URL https://github.com/LuaJIT/LuaJIT/archive/f73e649a954b599fc184726c376476e7a5c439ca.tar.gz
LUAJIT_SHA256 bc992b3ae0a8f5f0ebbf141626b7c99fac794c94ec6896d973582525c7ef868d
LUA_URL https://www.lua.org/ftp/lua-5.1.5.tar.gz
LUA_SHA256 2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333
@ -50,8 +50,8 @@ TREESITTER_QUERY_URL https://github.com/tree-sitter-grammars/tree-sitter-query/a
TREESITTER_QUERY_SHA256 d3a423ab66dc62b2969625e280116678a8a22582b5ff087795222108db2f6a6e
TREESITTER_MARKDOWN_URL https://github.com/tree-sitter-grammars/tree-sitter-markdown/archive/v0.3.2.tar.gz
TREESITTER_MARKDOWN_SHA256 5dac48a6d971eb545aab665d59a18180d21963afc781bbf40f9077c06cb82ae5
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/e3c82633389256ccc2c5ab2e509046cbf20453d3.tar.gz
TREESITTER_SHA256 61a21f5d83cfe256472bfa941123a6941fb45073784ee7ec0bc32fdd52f7a4e4
TREESITTER_URL https://github.com/tree-sitter/tree-sitter/archive/v0.24.5.tar.gz
TREESITTER_SHA256 b5ac48acf5a04fd82ccd4246ad46354d9c434be26c9606233917549711e4252c
WASMTIME_URL https://github.com/bytecodealliance/wasmtime/archive/v25.0.2.tar.gz
WASMTIME_SHA256 6d1c17c756b83f29f629963228e5fa208ba9d6578421ba2cd07132b6a120accb

View File

@ -19,6 +19,7 @@ if(APPLE)
endif()
find_program(CACHE_PRG NAMES ccache sccache)
mark_as_advanced(CACHE_PRG)
if(CACHE_PRG)
set(CMAKE_C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E env CCACHE_SLOPPINESS=pch_defines,time_macros ${CACHE_PRG})
list(APPEND DEPS_CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER_LAUNCHER:STRING=${CMAKE_C_COMPILER_LAUNCHER})
@ -27,6 +28,7 @@ endif()
# MAKE_PRG
if(UNIX)
find_program(MAKE_PRG NAMES gmake make)
mark_as_advanced(MAKE_PRG)
if(NOT MAKE_PRG)
message(FATAL_ERROR "GNU Make is required to build the dependencies.")
else()

View File

@ -167,13 +167,15 @@ function! s:Spawn(server_cmd, client_cmd, server_addr, reconnect)
if type(a:server_cmd) == type('')
" spawn gdbserver in a vertical split
let server = s:GdbServer.new(gdb)
vsp | enew | let gdb._server_id = termopen(a:server_cmd, server)
server.term = v:true
vsp | enew | let gdb._server_id = jobstart(a:server_cmd, server)
let gdb._jump_window = 2
let gdb._server_buf = bufnr('%')
endif
" go to the bottom window and spawn gdb client
wincmd j
enew | let gdb._client_id = termopen(a:client_cmd, gdb)
gdb.term = v:true
enew | let gdb._client_id = jobstart(a:client_cmd, gdb)
let gdb._client_buf = bufnr('%')
tnoremap <silent> <f8> <c-\><c-n>:GdbContinue<cr>i
tnoremap <silent> <f10> <c-\><c-n>:GdbNext<cr>i

View File

@ -1,6 +1,6 @@
" Vim autoload file for editing compressed files.
" Maintainer: The Vim Project <https://github.com/vim/vim>
" Last Change: 2023 Aug 10
" Last Change: 2024 Nov 25
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" These functions are used by the gzip plugin.
@ -148,6 +148,9 @@ fun gzip#read(cmd)
else
let fname = escape(expand("%:r"), " \t\n*?[{`$\\%#'\"|!<")
endif
if filereadable(undofile(expand("%")))
exe "sil rundo " . fnameescape(undofile(expand("%")))
endif
if &verbose >= 8
execute "doau BufReadPost " . fname
else

View File

@ -38,6 +38,9 @@
" 2024 Nov 14 by Vim Project: small fixes to netrw#BrowseX (#16056)
" 2024 Nov 23 by Vim Project: update decompress defaults (#16104)
" 2024 Nov 23 by Vim Project: fix powershell escaping issues (#16094)
" 2024 Dec 04 by Vim Project: do not detach for gvim (#16168)
" 2024 Dec 08 by Vim Project: check the first arg of netrw_browsex_viewer for being executable (#16185)
" 2024 Dec 12 by Vim Project: do not pollute the search history (#16206)
" }}}
" Former Maintainer: Charles E Campbell
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
@ -5040,7 +5043,7 @@ if has('unix')
endfun
else
fun! netrw#Launch(args)
exe ':silent ! nohup' a:args s:redir() '&' | redraw!
exe ':silent ! nohup' a:args s:redir() (has('gui_running') ? '' : '&') | redraw!
endfun
endif
elseif has('win32')
@ -5070,7 +5073,9 @@ elseif executable('open')
endif
fun! s:viewer()
if exists('g:netrw_browsex_viewer') && executable(g:netrw_browsex_viewer)
" g:netrw_browsex_viewer could be a string of program + its arguments,
" test if first argument is executable
if exists('g:netrw_browsex_viewer') && executable(split(g:netrw_browsex_viewer)[0])
" extract any viewing options. Assumes that they're set apart by spaces.
" call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
if g:netrw_browsex_viewer =~ '\s'
@ -11755,7 +11760,8 @@ endfun
" s:ShowLink: used to modify thin and tree listings to show links {{{2
fun! s:ShowLink()
if exists("b:netrw_curdir")
norm! $?\a
keepp :norm! $?\a
"call histdel("/",-1)
if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treetop")
let basedir = s:NetrwTreePath(w:netrw_treetop)
else

View File

@ -158,7 +158,7 @@ function! provider#clipboard#Executable() abort
let s:copy['*'] = s:copy['+']
let s:paste['*'] = s:paste['+']
return 'termux-clipboard'
elseif !empty($TMUX) && executable('tmux')
elseif executable('tmux') && (!empty($TMUX) || 0 == jobwait([jobstart(['tmux', 'list-buffers'])], 2000)[0])
let tmux_v = v:lua.vim.version.parse(system(['tmux', '-V']))
if !empty(tmux_v) && !v:lua.vim.version.lt(tmux_v, [3,2,0])
let s:copy['+'] = ['tmux', 'load-buffer', '-w', '-']

View File

@ -0,0 +1,250 @@
" Default pre- and post-compiler actions for SpotBugs
" Maintainers: @konfekt and @zzzyxwvut
" Last Change: 2024 Nov 27
let s:save_cpo = &cpo
set cpo&vim
if v:version > 900
function! spotbugs#DeleteClassFiles() abort
if !exists('b:spotbugs_class_files')
return
endif
for pathname in b:spotbugs_class_files
let classname = pathname =~# "^'.\\+\\.class'$"
\ ? eval(pathname)
\ : pathname
if classname =~# '\.class$' && filereadable(classname)
" Since v9.0.0795.
let octad = readblob(classname, 0, 8)
" Test the magic number and the major version number (45 for v1.0).
" Since v9.0.2027.
if len(octad) == 8 && octad[0 : 3] == 0zcafe.babe &&
\ or((octad[6] << 8), octad[7]) >= 45
echomsg printf('Deleting %s: %d', classname, delete(classname))
endif
endif
endfor
let b:spotbugs_class_files = []
endfunction
else
function! s:DeleteClassFilesWithNewLineCodes(classname) abort
" The distribution of "0a"s in class file versions 2560 and 2570:
"
" 0zca.fe.ba.be.00.00.0a.00 0zca.fe.ba.be.00.00.0a.0a
" 0zca.fe.ba.be.00.0a.0a.00 0zca.fe.ba.be.00.0a.0a.0a
" 0zca.fe.ba.be.0a.00.0a.00 0zca.fe.ba.be.0a.00.0a.0a
" 0zca.fe.ba.be.0a.0a.0a.00 0zca.fe.ba.be.0a.0a.0a.0a
let numbers = [0, 0, 0, 0, 0, 0, 0, 0]
let offset = 0
let lines = readfile(a:classname, 'b', 4)
" Track NL byte counts to handle files of less than 8 bytes.
let nl_cnt = len(lines)
" Track non-NL byte counts for "0zca.fe.ba.be.0a.0a.0a.0a".
let non_nl_cnt = 0
for line in lines
for idx in range(strlen(line))
" Remap NLs to Nuls.
let numbers[offset] = (line[idx] == "\n") ? 0 : char2nr(line[idx]) % 256
let non_nl_cnt += 1
let offset += 1
if offset > 7
break
endif
endfor
let nl_cnt -= 1
if offset > 7 || (nl_cnt < 1 && non_nl_cnt > 4)
break
endif
" Reclaim NLs.
let numbers[offset] = 10
let offset += 1
if offset > 7
break
endif
endfor
" Test the magic number and the major version number (45 for v1.0).
if offset > 7 && numbers[0] == 0xca && numbers[1] == 0xfe &&
\ numbers[2] == 0xba && numbers[3] == 0xbe &&
\ (numbers[6] * 256 + numbers[7]) >= 45
echomsg printf('Deleting %s: %d', a:classname, delete(a:classname))
endif
endfunction
function! spotbugs#DeleteClassFiles() abort
if !exists('b:spotbugs_class_files')
return
endif
let encoding = &encoding
try
set encoding=latin1
for pathname in b:spotbugs_class_files
let classname = pathname =~# "^'.\\+\\.class'$"
\ ? eval(pathname)
\ : pathname
if classname =~# '\.class$' && filereadable(classname)
let line = get(readfile(classname, 'b', 1), 0, '')
let length = strlen(line)
" Test the magic number and the major version number (45 for v1.0).
if length > 3 && line[0 : 3] == "\xca\xfe\xba\xbe"
if length > 7 && ((line[6] == "\n" ? 0 : char2nr(line[6]) % 256) * 256 +
\ (line[7] == "\n" ? 0 : char2nr(line[7]) % 256)) >= 45
echomsg printf('Deleting %s: %d', classname, delete(classname))
else
call s:DeleteClassFilesWithNewLineCodes(classname)
endif
endif
endif
endfor
finally
let &encoding = encoding
endtry
let b:spotbugs_class_files = []
endfunction
endif
function! spotbugs#DefaultPostCompilerAction() abort
" Since v7.4.191.
make %:S
endfunction
" Look for "spotbugs#compiler" in "ftplugin/java.vim".
let s:compiler = exists('spotbugs#compiler') ? spotbugs#compiler : ''
let s:readable = filereadable($VIMRUNTIME . '/compiler/' . s:compiler . '.vim')
if s:readable && s:compiler ==# 'maven' && executable('mvn')
function! spotbugs#DefaultPreCompilerAction() abort
call spotbugs#DeleteClassFiles()
compiler maven
make compile
endfunction
function! spotbugs#DefaultPreCompilerTestAction() abort
call spotbugs#DeleteClassFiles()
compiler maven
make test-compile
endfunction
function! spotbugs#DefaultProperties() abort
return {
\ 'PreCompilerAction':
\ function('spotbugs#DefaultPreCompilerAction'),
\ 'PreCompilerTestAction':
\ function('spotbugs#DefaultPreCompilerTestAction'),
\ 'PostCompilerAction':
\ function('spotbugs#DefaultPostCompilerAction'),
\ 'sourceDirPath': 'src/main/java',
\ 'classDirPath': 'target/classes',
\ 'testSourceDirPath': 'src/test/java',
\ 'testClassDirPath': 'target/test-classes',
\ }
endfunction
unlet s:readable s:compiler
elseif s:readable && s:compiler ==# 'ant' && executable('ant')
function! spotbugs#DefaultPreCompilerAction() abort
call spotbugs#DeleteClassFiles()
compiler ant
make compile
endfunction
function! spotbugs#DefaultPreCompilerTestAction() abort
call spotbugs#DeleteClassFiles()
compiler ant
make compile-test
endfunction
function! spotbugs#DefaultProperties() abort
return {
\ 'PreCompilerAction':
\ function('spotbugs#DefaultPreCompilerAction'),
\ 'PreCompilerTestAction':
\ function('spotbugs#DefaultPreCompilerTestAction'),
\ 'PostCompilerAction':
\ function('spotbugs#DefaultPostCompilerAction'),
\ 'sourceDirPath': 'src',
\ 'classDirPath': 'build/classes',
\ 'testSourceDirPath': 'test',
\ 'testClassDirPath': 'build/test/classes',
\ }
endfunction
unlet s:readable s:compiler
elseif s:readable && s:compiler ==# 'javac' && executable('javac')
function! spotbugs#DefaultPreCompilerAction() abort
call spotbugs#DeleteClassFiles()
compiler javac
if get(b:, 'javac_makeprg_params', get(g:, 'javac_makeprg_params', '')) =~ '\s@\S'
" Read options and filenames from @options [@sources ...].
make
else
" Let Javac figure out what files to compile.
execute 'make ' . join(map(filter(copy(v:argv),
\ "v:val =~# '\\.java\\=$'"),
\ 'shellescape(v:val)'), ' ')
endif
endfunction
function! spotbugs#DefaultPreCompilerTestAction() abort
call spotbugs#DefaultPreCompilerAction()
endfunction
function! spotbugs#DefaultProperties() abort
return {
\ 'PreCompilerAction':
\ function('spotbugs#DefaultPreCompilerAction'),
\ 'PreCompilerTestAction':
\ function('spotbugs#DefaultPreCompilerTestAction'),
\ 'PostCompilerAction':
\ function('spotbugs#DefaultPostCompilerAction'),
\ }
endfunction
unlet s:readable s:compiler
else
function! spotbugs#DefaultPreCompilerAction() abort
echomsg printf('Not supported: "%s"', s:compiler)
endfunction
function! spotbugs#DefaultPreCompilerTestAction() abort
call spotbugs#DefaultPreCompilerAction()
endfunction
function! spotbugs#DefaultProperties() abort
return {}
endfunction
unlet s:readable
endif
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: set foldmethod=syntax shiftwidth=2 expandtab:

View File

@ -1,6 +1,7 @@
" Language: Typst
" Maintainer: Gregory Anders
" Last Change: 2024 Nov 02
" Previous Maintainer: Gregory Anders
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
" Last Change: 2024 Dec 09
" Based on: https://github.com/kaarmu/typst.vim
function! typst#indentexpr() abort

View File

@ -60,6 +60,7 @@ hi('PmenuMatch', { link = 'Pmenu' })
hi('PmenuMatchSel', { link = 'PmenuSel' })
hi('PmenuExtra', { link = 'Pmenu' })
hi('PmenuExtraSel', { link = 'PmenuSel' })
hi('ComplMatchIns', { link = 'Normal' })
hi('Substitute', { link = 'Search' })
hi('Whitespace', { link = 'NonText' })
hi('MsgSeparator', { link = 'StatusLine' })

View File

@ -1,13 +1,12 @@
" Vim compiler file
" Compiler: ESLint for JavaScript
" Maintainer: Romain Lafourcade <romainlafourcade@gmail.com>
" Last Change: 2020 August 20
" 2024 Apr 03 by The Vim Project (removed :CompilerSet definition)
" Last Change: 2024 Nov 30
if exists("current_compiler")
finish
endif
let current_compiler = "eslint"
CompilerSet makeprg=npx\ eslint\ --format\ compact
CompilerSet errorformat=%f:\ line\ %l\\,\ col\ %c\\,\ %m,%-G%.%#
CompilerSet makeprg=npx\ eslint\ --format\ stylish
CompilerSet errorformat=%-P%f,\%\\s%#%l:%c\ %#\ %trror\ \ %m,\%\\s%#%l:%c\ %#\ %tarning\ \ %m,\%-Q,\%-G%.%#,

View File

@ -1,7 +1,7 @@
" Vim compiler file
" Compiler: Java Development Kit Compiler
" Maintainer: Doug Kearns <dougkearns@gmail.com>
" Last Change: 2024 Jun 14
" Last Change: 2024 Nov 19 (enable local javac_makeprg_params)
if exists("current_compiler")
finish
@ -11,11 +11,7 @@ let current_compiler = "javac"
let s:cpo_save = &cpo
set cpo&vim
if exists("g:javac_makeprg_params")
execute $'CompilerSet makeprg=javac\ {escape(g:javac_makeprg_params, ' \|"')}'
else
CompilerSet makeprg=javac
endif
execute $'CompilerSet makeprg=javac\ {escape(get(b:, 'javac_makeprg_params', get(g:, 'javac_makeprg_params', '')), ' \|"')}'
CompilerSet errorformat=%E%f:%l:\ error:\ %m,
\%W%f:%l:\ warning:\ %m,

View File

@ -14,7 +14,7 @@ if exists("current_compiler")
endif
let current_compiler = "maven"
CompilerSet makeprg=mvn\ --batch-mode
execute $'CompilerSet makeprg=mvn\ --batch-mode\ {escape(get(b:, 'maven_makeprg_params', get(g:, 'maven_makeprg_params', '')), ' \|"')}'
" Error message for POM
CompilerSet errorformat=[FATAL]\ Non-parseable\ POM\ %f:\ %m%\\s%\\+@%.%#line\ %l\\,\ column\ %c%.%#,

103
runtime/compiler/pytest.vim Normal file
View File

@ -0,0 +1,103 @@
" Vim compiler file
" Compiler: Pytest (Python testing framework)
" Maintainer: @Konfekt and @mgedmin
" Last Change: 2024 Nov 28
if exists("current_compiler") | finish | endif
let current_compiler = "pytest"
let s:cpo_save = &cpo
set cpo&vim
" CompilerSet makeprg=pytest
if has('unix')
execute $'CompilerSet makeprg=/usr/bin/env\ PYTHONWARNINGS=ignore\ pytest\ {escape(get(b:, 'pytest_makeprg_params', get(g:, 'pytest_makeprg_params', '--tb=short --quiet')), ' \|"')}'
elseif has('win32')
execute $'CompilerSet makeprg=set\ PYTHONWARNINGS=ignore\ &&\ pytest\ {escape(get(b:, 'pytest_makeprg_params', get(g:, 'pytest_makeprg_params', '--tb=short --quiet')), ' \|"')}'
else
CompilerSet makeprg=pytest\ --tb=short\ --quiet
execute $'CompilerSet makeprg=pytest\ {escape(get(b:, 'pytest_makeprg_params', get(g:, 'pytest_makeprg_params', '--tb=short --quiet')), ' \|"')}'
endif
" Pytest syntax errors {{{2
" Reset error format so that sourcing .vimrc again and again doesn't grow it
" without bounds
setlocal errorformat&
" For the record, the default errorformat is this:
"
" %*[^"]"%f"%*\D%l: %m
" "%f"%*\D%l: %m
" %-G%f:%l: (Each undeclared identifier is reported only once
" %-G%f:%l: for each function it appears in.)
" %-GIn file included from %f:%l:%c:
" %-GIn file included from %f:%l:%c\,
" %-GIn file included from %f:%l:%c
" %-GIn file included from %f:%l
" %-G%*[ ]from %f:%l:%c
" %-G%*[ ]from %f:%l:
" %-G%*[ ]from %f:%l\,
" %-G%*[ ]from %f:%l
" %f:%l:%c:%m
" %f(%l):%m
" %f:%l:%m
" "%f"\, line %l%*\D%c%*[^ ] %m
" %D%*\a[%*\d]: Entering directory %*[`']%f'
" %X%*\a[%*\d]: Leaving directory %*[`']%f'
" %D%*\a: Entering directory %*[`']%f'
" %X%*\a: Leaving directory %*[`']%f'
" %DMaking %*\a in %f
" %f|%l| %m
"
" and sometimes it misfires, so let's fix it up a bit
" (TBH I don't even know what compiler produces filename(lineno) so why even
" have it?)
setlocal errorformat-=%f(%l):%m
" Sometimes Vim gets confused about ISO-8601 timestamps and thinks they're
" filenames; this is a big hammer that ignores anything filename-like on lines
" that start with at least two spaces, possibly preceded by a number and
" optional punctuation
setlocal errorformat^=%+G%\\d%#%.%\\=\ \ %.%#
" Similar, but when the entire line starts with a date
setlocal errorformat^=%+G\\d\\d\\d\\d-\\d\\d-\\d\\d\ \\d\\d:\\d\\d%.%#
" make: *** [Makefile:14: target] Error 1
setlocal errorformat^=%+Gmake:\ ***\ %.%#
" FAILED tests.py::test_with_params[YYYY-MM-DD:HH:MM:SS] - Exception: bla bla
setlocal errorformat^=%+GFAILED\ %.%#
" AssertionError: assert ...YYYY-MM-DD:HH:MM:SS...
setlocal errorformat^=%+GAssertionError:\ %.%#
" --- /path/to/file:before YYYY-MM-DD HH:MM:SS.ssssss
setlocal errorformat^=---%f:%m
" +++ /path/to/file:before YYYY-MM-DD HH:MM:SS.ssssss
setlocal errorformat^=+++%f:%m
" Sometimes pytest prepends an 'E' marker at the beginning of a traceback line
setlocal errorformat+=E\ %#File\ \"%f\"\\,\ line\ %l%.%#
" Python tracebacks (unittest + doctest output) {{{2
" This collapses the entire traceback into just the last file+lineno,
" which is convenient when you want to jump to the line that failed (and not
" the top-level entry point), but it makes it impossible to see the full
" traceback, which sucks.
""setlocal errorformat+=
"" \File\ \"%f\"\\,\ line\ %l%.%#,
"" \%C\ %.%#,
"" \%-A\ \ File\ \"unittest%.py\"\\,\ line\ %.%#,
"" \%-A\ \ File\ \"%f\"\\,\ line\ 0%.%#,
"" \%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,
"" \%Z%[%^\ ]%\\@=%m
setlocal errorformat+=File\ \"%f\"\\,\ line\ %l\\,%#%m
exe 'CompilerSet errorformat='..escape(&l:errorformat, ' \|"')
let &cpo = s:cpo_save
unlet s:cpo_save

View File

@ -0,0 +1,189 @@
" Vim compiler file
" Compiler: Spotbugs (Java static checker; needs javac compiled classes)
" Maintainer: @konfekt and @zzzyxwvut
" Last Change: 2024 Nov 27
if exists('g:current_compiler') || bufname() !~# '\.java\=$' || wordcount().chars < 9
finish
endif
let s:cpo_save = &cpo
set cpo&vim
" Unfortunately Spotbugs does not output absolute paths, so you need to
" pass the directory of the files being checked as `-sourcepath` parameter.
" The regex, auxpath and glob try to include all dependent classes of the
" current buffer. See https://github.com/spotbugs/spotbugs/issues/856
" FIXME: When "search()" is used with the "e" flag, it makes no _further_
" progress after claiming an EOL match (i.e. "\_" or "\n", but not "$").
" XXX: Omit anonymous class declarations
let s:keywords = '\C\<\%(\.\@1<!class\|@\=interface\|enum\|record\|package\)\%(\s\|$\)'
let s:type_names = '\C\<\%(\.\@1<!class\|@\=interface\|enum\|record\)\s*\(\K\k*\)\>'
" Capture ";" for counting a class file directory (see s:package_dir_heads below)
let s:package_names = '\C\<package\s*\(\K\%(\k*\.\=\)\+;\)'
let s:package = ''
if has('syntax') && exists('g:syntax_on') && exists('b:current_syntax') &&
\ b:current_syntax == 'java' && hlexists('javaClassDecl')
function! s:GetDeclaredTypeNames() abort
if bufname() =~# '\<\%(module\|package\)-info\.java\=$'
return [expand('%:t:r')]
endif
defer execute('silent! normal! g``')
call cursor(1, 1)
let type_names = []
let lnum = search(s:keywords, 'eW')
while lnum > 0
let name_attr = synIDattr(synID(lnum, (col('.') - 1), 0), 'name')
if name_attr ==# 'javaClassDecl'
let tokens = matchlist(getline(lnum)..getline(lnum + 1), s:type_names)
if !empty(tokens) | call add(type_names, tokens[1]) | endif
elseif name_attr ==# 'javaExternal'
let tokens = matchlist(getline(lnum)..getline(lnum + 1), s:package_names)
if !empty(tokens) | let s:package = tokens[1] | endif
endif
let lnum = search(s:keywords, 'eW')
endwhile
return type_names
endfunction
else
function! s:GetDeclaredTypeNames() abort
if bufname() =~# '\<\%(module\|package\)-info\.java\=$'
return [expand('%:t:r')]
endif
" Undo the unsetting of &hls, see below
if &hls
defer execute('set hls')
endif
" Possibly restore the current values for registers '"' and "y", see below
defer call('setreg', ['"', getreg('"'), getregtype('"')])
defer call('setreg', ['y', getreg('y'), getregtype('y')])
defer execute('silent bwipeout')
" Copy buffer contents for modification
silent %y y
new
" Apply ":help scratch-buffer" effects and match "$" in Java (generated)
" type names (see s:type_names)
setlocal iskeyword+=$ buftype=nofile bufhidden=hide noswapfile nohls
0put y
" Discard text blocks and strings
silent keeppatterns %s/\\\@<!"""\_.\{-}\\\@<!"""\|\\"//ge
silent keeppatterns %s/".*"//ge
" Discard comments
silent keeppatterns %s/\/\/.\+$//ge
silent keeppatterns %s/\/\*\_.\{-}\*\///ge
call cursor(1, 1)
let type_names = []
let lnum = search(s:keywords, 'eW')
while lnum > 0
let line = getline(lnum)
if line =~# '\<package\>'
let tokens = matchlist(line..getline(lnum + 1), s:package_names)
if !empty(tokens) | let s:package = tokens[1] | endif
else
let tokens = matchlist(line..getline(lnum + 1), s:type_names)
if !empty(tokens) | call add(type_names, tokens[1]) | endif
endif
let lnum = search(s:keywords, 'eW')
endwhile
return type_names
endfunction
endif
if has('win32')
function! s:GlobClassFiles(src_type_name) abort
return glob(a:src_type_name..'$*.class', 1, 1)
endfunction
else
function! s:GlobClassFiles(src_type_name) abort
return glob(a:src_type_name..'\$*.class', 1, 1)
endfunction
endif
if exists('g:spotbugs_properties') &&
\ (has_key(g:spotbugs_properties, 'sourceDirPath') &&
\ has_key(g:spotbugs_properties, 'classDirPath')) ||
\ (has_key(g:spotbugs_properties, 'testSourceDirPath') &&
\ has_key(g:spotbugs_properties, 'testClassDirPath'))
function! s:FindClassFiles(src_type_name) abort
let class_files = []
" Match pairwise the components of source and class pathnames
for [src_dir, bin_dir] in filter([
\ [get(g:spotbugs_properties, 'sourceDirPath', ''),
\ get(g:spotbugs_properties, 'classDirPath', '')],
\ [get(g:spotbugs_properties, 'testSourceDirPath', ''),
\ get(g:spotbugs_properties, 'testClassDirPath', '')]],
\ '!(empty(v:val[0]) || empty(v:val[1]))')
" Since only the rightmost "src" is sought, while there can be any number of
" such filenames, no "fnamemodify(a:src_type_name, ':p:s?src?bin?')" is used
let tail_idx = strridx(a:src_type_name, src_dir)
" No such directory or no such inner type (i.e. without "$")
if tail_idx < 0 | continue | endif
" Substitute "bin_dir" for the rightmost "src_dir"
let candidate_type_name = strpart(a:src_type_name, 0, tail_idx)..
\ bin_dir..
\ strpart(a:src_type_name, (tail_idx + strlen(src_dir)))
for candidate in insert(s:GlobClassFiles(candidate_type_name),
\ candidate_type_name..'.class')
if filereadable(candidate) | call add(class_files, shellescape(candidate)) | endif
endfor
if !empty(class_files) | break | endif
endfor
return class_files
endfunction
else
function! s:FindClassFiles(src_type_name) abort
let class_files = []
for candidate in insert(s:GlobClassFiles(a:src_type_name),
\ a:src_type_name..'.class')
if filereadable(candidate) | call add(class_files, shellescape(candidate)) | endif
endfor
return class_files
endfunction
endif
function! s:CollectClassFiles() abort
" Get a platform-independent pathname prefix, cf. "expand('%:p:h')..'/'"
let pathname = expand('%:p')
let tail_idx = strridx(pathname, expand('%:t'))
let src_pathname = strpart(pathname, 0, tail_idx)
let all_class_files = []
" Get all type names in the current buffer and let the filename globbing
" discover inner type names from arbitrary type names
for type_name in s:GetDeclaredTypeNames()
call extend(all_class_files, s:FindClassFiles(src_pathname..type_name))
endfor
return all_class_files
endfunction
" Expose class files for removal etc.
let b:spotbugs_class_files = s:CollectClassFiles()
let s:package_dir_heads = repeat(':h', (1 + strlen(substitute(s:package, '[^.;]', '', 'g'))))
let g:current_compiler = 'spotbugs'
" CompilerSet makeprg=spotbugs
let &l:makeprg = 'spotbugs'..(has('win32') ? '.bat' : '')..' '..
\ get(b:, 'spotbugs_makeprg_params', get(g:, 'spotbugs_makeprg_params', '-workHard -experimental'))..
\ ' -textui -emacs -auxclasspath %:p'..s:package_dir_heads..':S -sourcepath %:p'..s:package_dir_heads..':S '..
\ join(b:spotbugs_class_files, ' ')
" Emacs expects doubled line numbers
setlocal errorformat=%f:%l:%*[0-9]\ %m,%f:-%*[0-9]:-%*[0-9]\ %m
" " This compiler is meant to be used for a single buffer only
" exe 'CompilerSet makeprg='..escape(&l:makeprg, ' \|"')
" exe 'CompilerSet errorformat='..escape(&l:errorformat, ' \|"')
delfunction s:CollectClassFiles
delfunction s:FindClassFiles
delfunction s:GlobClassFiles
delfunction s:GetDeclaredTypeNames
let &cpo = s:cpo_save
unlet s:package_dir_heads s:package s:package_names s:type_names s:keywords s:cpo_save
" vim: set foldmethod=syntax shiftwidth=2 expandtab:

View File

@ -1,7 +1,8 @@
" Vim compiler file
" Language: Typst
" Maintainer: Gregory Anders
" Last Change: 2024-07-14
" Previous Maintainer: Gregory Anders
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
" Last Change: 2024 Dec 09
" Based on: https://github.com/kaarmu/typst.vim
if exists('current_compiler')

View File

@ -1114,7 +1114,7 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
Open a terminal instance in a buffer
By default (and currently the only option) the terminal will not be
connected to an external process. Instead, input send on the channel will
connected to an external process. Instead, input sent on the channel will
be echoed directly by the terminal. This is useful to display ANSI
terminal sequences returned as part of a rpc message, or similar.
@ -1125,6 +1125,17 @@ nvim_open_term({buffer}, {opts}) *nvim_open_term()*
|nvim_chan_send()| can be called immediately to process sequences in a
virtual terminal having the intended size.
Example: this `TermHl` command can be used to display and highlight raw
ANSI termcodes, so you can use Nvim as a "scrollback pager" (for terminals
like kitty): *terminal-scrollback-pager* >lua
vim.api.nvim_create_user_command('TermHl', function()
local b = vim.api.nvim_create_buf(false, true)
local chan = vim.api.nvim_open_term(b, {})
vim.api.nvim_chan_send(chan, table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n'))
vim.api.nvim_win_set_buf(0, b)
end, { desc = 'Highlights ANSI termcodes in curbuf' })
<
Attributes: ~
not allowed when |textlock| is active
@ -1636,11 +1647,9 @@ nvim_command({command}) *nvim_command()*
On execution error: fails with Vimscript error, updates v:errmsg.
Prefer using |nvim_cmd()| or |nvim_exec2()| over this. To evaluate
multiple lines of Vim script or an Ex command directly, use
|nvim_exec2()|. To construct an Ex command using a structured format and
then execute it, use |nvim_cmd()|. To modify an Ex command before
evaluating it, use |nvim_parse_cmd()| in conjunction with |nvim_cmd()|.
Prefer |nvim_cmd()| or |nvim_exec2()| instead. To modify an Ex command in
a structured way before executing it, modify the result of
|nvim_parse_cmd()| then pass it to |nvim_cmd()|.
Parameters: ~
• {command} Ex command string
@ -2161,12 +2170,12 @@ nvim_buf_call({buffer}, {fun}) *nvim_buf_call()*
This temporarily switches current buffer to "buffer". If the current
window already shows "buffer", the window is not switched. If a window
inside the current tabpage (including a float) already shows the buffer,
then one of these windows will be set as current window temporarily.
then one of those windows will be set as current window temporarily.
Otherwise a temporary scratch window (called the "autocmd window" for
historical reasons) will be used.
This is useful e.g. to call Vimscript functions that only work with the
current buffer/window currently, like |termopen()|.
current buffer/window currently, like `jobstart(…, {'term': v:true})`.
Attributes: ~
Lua |vim.api| only
@ -3483,9 +3492,9 @@ nvim_create_autocmd({event}, {opts}) *nvim_create_autocmd()*
• event: (string) name of the triggered event
|autocmd-events|
• group: (number|nil) autocommand group id, if any
match: (string) expanded value of <amatch>
buf: (number) expanded value of <abuf>
file: (string) expanded value of <afile>
file: (string) <afile> (not expanded to a full path)
match: (string) <amatch> (expanded to a full path)
buf: (number) <abuf>
• data: (any) arbitrary data passed from
|nvim_exec_autocmds()| *event-data*
• command (string) optional: Vim command to execute on event.

View File

@ -463,6 +463,10 @@ CompleteDone After Insert mode completion is done. Either
|v:completed_item| gives the completed item.
Sets these |v:event| keys:
complete_word The word that was
selected, empty if
abandoned complete.
complete_type |complete_info_mode|
reason Reason for completion being
done. Can be one of:
- "accept": completion was

233
runtime/doc/builtin.txt generated
View File

@ -1305,10 +1305,10 @@ copy({expr}) *copy()*
Also see |deepcopy()|.
Parameters: ~
• {expr} (`any`)
• {expr} (`T`)
Return: ~
(`any`)
(`T`)
cos({expr}) *cos()*
Return the cosine of {expr}, measured in radians, as a |Float|.
@ -1407,7 +1407,7 @@ ctxset({context} [, {index}]) *ctxset()*
• {index} (`integer?`)
Return: ~
(`any`)
(`integer`)
ctxsize() *ctxsize()*
Returns the size of the |context-stack|.
@ -1490,11 +1490,11 @@ deepcopy({expr} [, {noref}]) *deepcopy()* *E69
Also see |copy()|.
Parameters: ~
• {expr} (`any`)
• {expr} (`T`)
• {noref} (`boolean?`)
Return: ~
(`any`)
(`T`)
delete({fname} [, {flags}]) *delete()*
Without {flags} or with {flags} empty: Deletes the file by the
@ -1618,7 +1618,7 @@ did_filetype() *did_filetype()*
file.
Return: ~
(`any`)
(`integer`)
diff_filler({lnum}) *diff_filler()*
Returns the number of filler lines above line {lnum}.
@ -1633,7 +1633,7 @@ diff_filler({lnum}) *diff_filler()*
• {lnum} (`integer`)
Return: ~
(`any`)
(`integer`)
diff_hlID({lnum}, {col}) *diff_hlID()*
Returns the highlight ID for diff mode at line {lnum} column
@ -1674,7 +1674,7 @@ digraph_get({chars}) *digraph_get()* *E121
• {chars} (`string`)
Return: ~
(`any`)
(`string`)
digraph_getlist([{listall}]) *digraph_getlist()*
Return a list of digraphs. If the {listall} argument is given
@ -1695,7 +1695,7 @@ digraph_getlist([{listall}]) *digraph_getlist()*
• {listall} (`boolean?`)
Return: ~
(`any`)
(`string[][]`)
digraph_set({chars}, {digraph}) *digraph_set()*
Add digraph {chars} to the list. {chars} must be a string
@ -1756,7 +1756,7 @@ empty({expr}) *empty()*
• {expr} (`any`)
Return: ~
(`any`)
(`integer`)
environ() *environ()*
Return all of environment variables as dictionary. You can
@ -1783,7 +1783,7 @@ escape({string}, {chars}) *escape()*
• {chars} (`string`)
Return: ~
(`any`)
(`string`)
eval({string}) *eval()*
Evaluate {string} and return the result. Especially useful to
@ -2666,7 +2666,7 @@ foreach({expr1}, {expr2}) *foreach()*
• {expr2} (`string|function`)
Return: ~
(`any`)
(`string|table`)
fullcommand({name}) *fullcommand()*
Get the full command name from a short abbreviated command
@ -2997,10 +2997,10 @@ getbufline({buf}, {lnum} [, {end}]) *getbufline()*
Parameters: ~
• {buf} (`integer|string`)
• {lnum} (`integer`)
• {end_} (`integer?`)
• {end} (`integer?`)
Return: ~
(`any`)
(`string[]`)
getbufoneline({buf}, {lnum}) *getbufoneline()*
Just like `getbufline()` but only get one line and return it
@ -3295,7 +3295,7 @@ getcmdscreenpos() *getcmdscreenpos()*
|setcmdline()|.
Return: ~
(`any`)
(`integer`)
getcmdtype() *getcmdtype()*
Return the current command-line type. Possible return values
@ -3635,7 +3635,7 @@ getline({lnum} [, {end}]) *getline()*
Parameters: ~
• {lnum} (`integer|string`)
• {end_} (`nil|false?`)
• {end} (`nil|false?`)
Return: ~
(`string`)
@ -4299,7 +4299,7 @@ gettext({text}) *gettext()*
• {text} (`string`)
Return: ~
(`any`)
(`string`)
getwininfo([{winid}]) *getwininfo()*
Returns information about windows as a |List| with Dictionaries.
@ -4315,6 +4315,8 @@ getwininfo([{winid}]) *getwininfo()*
botline last complete displayed buffer line
bufnr number of buffer in the window
height window height (excluding winbar)
leftcol first column displayed; only used when
'wrap' is off
loclist 1 if showing a location list
quickfix 1 if quickfix or location list window
terminal 1 if a terminal window
@ -4465,7 +4467,7 @@ glob2regpat({string}) *glob2regpat()*
• {string} (`string`)
Return: ~
(`any`)
(`string`)
globpath({path}, {expr} [, {nosuf} [, {list} [, {allinks}]]]) *globpath()*
Perform glob() for String {expr} on all directories in {path}
@ -4822,7 +4824,7 @@ iconv({string}, {from}, {to}) *iconv()*
• {to} (`string`)
Return: ~
(`any`)
(`string`)
id({expr}) *id()*
Returns a |String| which is a unique identifier of the
@ -4845,7 +4847,7 @@ id({expr}) *id()*
• {expr} (`any`)
Return: ~
(`any`)
(`string`)
indent({lnum}) *indent()*
The result is a Number, which is indent of line {lnum} in the
@ -4895,7 +4897,7 @@ index({object}, {expr} [, {start} [, {ic}]]) *index()*
• {ic} (`boolean?`)
Return: ~
(`any`)
(`integer`)
indexof({object}, {expr} [, {opts}]) *indexof()*
Returns the index of an item in {object} where {expr} is
@ -4942,7 +4944,7 @@ indexof({object}, {expr} [, {opts}]) *indexof()*
• {opts} (`table?`)
Return: ~
(`any`)
(`integer`)
input({prompt} [, {text} [, {completion}]]) *input()*
@ -4952,7 +4954,7 @@ input({prompt} [, {text} [, {completion}]]) *input()*
• {completion} (`string?`)
Return: ~
(`any`)
(`string`)
input({opts})
The result is a String, which is whatever the user typed on
@ -5069,7 +5071,7 @@ input({opts})
• {opts} (`table`)
Return: ~
(`any`)
(`string`)
inputlist({textlist}) *inputlist()*
{textlist} must be a |List| of strings. This |List| is
@ -5101,7 +5103,7 @@ inputrestore() *inputrestore()*
Returns TRUE when there is nothing to restore, FALSE otherwise.
Return: ~
(`any`)
(`integer`)
inputsave() *inputsave()*
Preserve typeahead (also from mappings) and clear it, so that
@ -5112,7 +5114,7 @@ inputsave() *inputsave()*
Returns TRUE when out of memory, FALSE otherwise.
Return: ~
(`any`)
(`integer`)
inputsecret({prompt} [, {text}]) *inputsecret()*
This function acts much like the |input()| function with but
@ -5130,7 +5132,7 @@ inputsecret({prompt} [, {text}]) *inputsecret()*
• {text} (`string?`)
Return: ~
(`any`)
(`string`)
insert({object}, {item} [, {idx}]) *insert()*
When {object} is a |List| or a |Blob| insert {item} at the start
@ -5181,10 +5183,10 @@ invert({expr}) *invert()*
<
Parameters: ~
• {expr} (`number`)
• {expr} (`integer`)
Return: ~
(`any`)
(`integer`)
isabsolutepath({path}) *isabsolutepath()*
The result is a Number, which is |TRUE| when {path} is an
@ -5279,7 +5281,7 @@ items({dict}) *items()*
the index.
Parameters: ~
• {dict} (`any`)
• {dict} (`table`)
Return: ~
(`any`)
@ -5307,7 +5309,7 @@ jobresize({job}, {width}, {height}) *jobresize()*
(`any`)
jobstart({cmd} [, {opts}]) *jobstart()*
Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
Spawns {cmd} as a job.
If {cmd} is a List it runs directly (no 'shell').
@ -5381,6 +5383,10 @@ jobstart({cmd} [, {opts}]) *jobstart()*
stdin: (string) Either "pipe" (default) to connect the
job's stdin to a channel or "null" to disconnect
stdin.
term: (boolean) Spawns {cmd} in a new pseudo-terminal session
connected to the current (unmodified) buffer. Implies "pty".
Default "height" and "width" are set to the current window
dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
width: (number) Width of the `pty` terminal.
{opts} is passed as |self| dictionary to the callback; the
@ -5397,7 +5403,7 @@ jobstart({cmd} [, {opts}]) *jobstart()*
• {opts} (`table?`)
Return: ~
(`any`)
(`integer`)
jobstop({id}) *jobstop()*
Stop |job-id| {id} by sending SIGTERM to the job process. If
@ -5413,7 +5419,7 @@ jobstop({id}) *jobstop()*
• {id} (`integer`)
Return: ~
(`any`)
(`integer`)
jobwait({jobs} [, {timeout}]) *jobwait()*
Waits for jobs and their |on_exit| handlers to complete.
@ -5441,7 +5447,7 @@ jobwait({jobs} [, {timeout}]) *jobwait()*
• {timeout} (`integer?`)
Return: ~
(`any`)
(`integer[]`)
join({list} [, {sep}]) *join()*
Join the items in {list} together into one String.
@ -5459,7 +5465,7 @@ join({list} [, {sep}]) *join()*
• {sep} (`string?`)
Return: ~
(`any`)
(`string`)
json_decode({expr}) *json_decode()*
Convert {expr} from JSON object. Accepts |readfile()|-style
@ -5498,7 +5504,7 @@ json_encode({expr}) *json_encode()*
• {expr} (`any`)
Return: ~
(`any`)
(`string`)
keys({dict}) *keys()*
Return a |List| with all the keys of {dict}. The |List| is in
@ -5508,7 +5514,7 @@ keys({dict}) *keys()*
• {dict} (`table`)
Return: ~
(`any`)
(`string[]`)
keytrans({string}) *keytrans()*
Turn the internal byte representation of keys into a form that
@ -5521,7 +5527,7 @@ keytrans({string}) *keytrans()*
• {string} (`string`)
Return: ~
(`any`)
(`string`)
len({expr}) *len()* *E701*
The result is a Number, which is the length of the argument.
@ -5535,10 +5541,10 @@ len({expr}) *len()* *E70
Otherwise an error is given and returns zero.
Parameters: ~
• {expr} (`any`)
• {expr} (`any[]`)
Return: ~
(`any`)
(`integer`)
libcall({libname}, {funcname}, {argument}) *libcall()* *E364* *E368*
Call function {funcname} in the run-time library {libname}
@ -5664,7 +5670,7 @@ lispindent({lnum}) *lispindent()*
• {lnum} (`integer`)
Return: ~
(`any`)
(`integer`)
list2blob({list}) *list2blob()*
Return a Blob concatenating all the number values in {list}.
@ -5680,7 +5686,7 @@ list2blob({list}) *list2blob()*
• {list} (`any[]`)
Return: ~
(`any`)
(`string`)
list2str({list} [, {utf8}]) *list2str()*
Convert each number in {list} to a character string can
@ -5703,14 +5709,14 @@ list2str({list} [, {utf8}]) *list2str()*
• {utf8} (`boolean?`)
Return: ~
(`any`)
(`string`)
localtime() *localtime()*
Return the current time, measured as seconds since 1st Jan
1970. See also |strftime()|, |strptime()| and |getftime()|.
Return: ~
(`any`)
(`integer`)
log({expr}) *log()*
Return the natural logarithm (base e) of {expr} as a |Float|.
@ -5727,7 +5733,7 @@ log({expr}) *log()*
• {expr} (`number`)
Return: ~
(`any`)
(`number`)
log10({expr}) *log10()*
Return the logarithm of Float {expr} to base 10 as a |Float|.
@ -5743,7 +5749,7 @@ log10({expr}) *log10()*
• {expr} (`number`)
Return: ~
(`any`)
(`number`)
luaeval({expr} [, {expr}]) *luaeval()*
Evaluate Lua expression {expr} and return its result converted
@ -6290,7 +6296,7 @@ matchbufline({buf}, {pat}, {lnum}, {end}, [, {dict}]) *matchbufline()*
• {buf} (`string|integer`)
• {pat} (`string`)
• {lnum} (`string|integer`)
• {end_} (`string|integer`)
• {end} (`string|integer`)
• {dict} (`table?`)
Return: ~
@ -6565,7 +6571,7 @@ max({expr}) *max()*
• {expr} (`any`)
Return: ~
(`any`)
(`number`)
menu_get({path} [, {modes}]) *menu_get()*
Returns a |List| of |Dictionaries| describing |menus| (defined
@ -6712,7 +6718,7 @@ min({expr}) *min()*
• {expr} (`any`)
Return: ~
(`any`)
(`number`)
mkdir({name} [, {flags} [, {prot}]]) *mkdir()* *E739*
Create directory {name}.
@ -6760,7 +6766,7 @@ mkdir({name} [, {flags} [, {prot}]]) *mkdir()* *E73
• {prot} (`string?`)
Return: ~
(`any`)
(`integer`)
mode([{expr}]) *mode()*
Return a string that indicates the current mode.
@ -6935,7 +6941,7 @@ nextnonblank({lnum}) *nextnonblank()*
• {lnum} (`integer`)
Return: ~
(`any`)
(`integer`)
nr2char({expr} [, {utf8}]) *nr2char()*
Return a string with a single character, which has the number
@ -6957,7 +6963,7 @@ nr2char({expr} [, {utf8}]) *nr2char()*
• {utf8} (`boolean?`)
Return: ~
(`any`)
(`string`)
nvim_...({...}) *nvim_...()* *E5555* *eval-api*
Call nvim |api| functions. The type checking of arguments will
@ -7014,7 +7020,7 @@ pathshorten({path} [, {len}]) *pathshorten()*
• {len} (`integer?`)
Return: ~
(`any`)
(`string`)
perleval({expr}) *perleval()*
Evaluate |perl| expression {expr} and return its result
@ -7054,7 +7060,7 @@ pow({x}, {y}) *pow()*
• {y} (`number`)
Return: ~
(`any`)
(`number`)
prevnonblank({lnum}) *prevnonblank()*
Return the line number of the first line at or above {lnum}
@ -7069,7 +7075,7 @@ prevnonblank({lnum}) *prevnonblank()*
• {lnum} (`integer`)
Return: ~
(`any`)
(`integer`)
printf({fmt}, {expr1} ...) *printf()*
Return a String with {fmt}, where "%" items are replaced by
@ -7731,11 +7737,11 @@ reduce({object}, {func} [, {initial}]) *reduce()* *E99
Parameters: ~
• {object} (`any`)
• {func} (`function`)
• {func} (`fun(accumulator: T, current: any): any`)
• {initial} (`any?`)
Return: ~
(`any`)
(`T`)
reg_executing() *reg_executing()*
Returns the single letter name of the register being executed.
@ -7784,7 +7790,7 @@ reltime({start}, {end})
Parameters: ~
• {start} (`any?`)
• {end_} (`any?`)
• {end} (`any?`)
Return: ~
(`any`)
@ -7845,7 +7851,7 @@ remove({list}, {idx}, {end})
Parameters: ~
• {list} (`any[]`)
• {idx} (`integer`)
• {end_} (`integer?`)
• {end} (`integer?`)
Return: ~
(`any`)
@ -7867,7 +7873,7 @@ remove({blob}, {idx}, {end})
Parameters: ~
• {blob} (`any`)
• {idx} (`integer`)
• {end_} (`integer?`)
• {end} (`integer?`)
Return: ~
(`any`)
@ -7899,7 +7905,7 @@ rename({from}, {to}) *rename()*
• {to} (`string`)
Return: ~
(`any`)
(`integer`)
repeat({expr}, {count}) *repeat()*
Repeat {expr} {count} times and return the concatenated
@ -7935,7 +7941,7 @@ resolve({filename}) *resolve()* *E65
• {filename} (`string`)
Return: ~
(`any`)
(`string`)
reverse({object}) *reverse()*
Reverse the order of items in {object}. {object} can be a
@ -7949,10 +7955,10 @@ reverse({object}) *reverse()*
<
Parameters: ~
• {object} (`any`)
• {object} (`T[]`)
Return: ~
(`any`)
(`T[]`)
round({expr}) *round()*
Round off {expr} to the nearest integral value and return it
@ -7972,7 +7978,7 @@ round({expr}) *round()*
• {expr} (`number`)
Return: ~
(`any`)
(`number`)
rpcnotify({channel}, {event} [, {args}...]) *rpcnotify()*
Sends {event} to {channel} via |RPC| and returns immediately.
@ -7984,10 +7990,10 @@ rpcnotify({channel}, {event} [, {args}...]) *rpcnotify()*
Parameters: ~
• {channel} (`integer`)
• {event} (`string`)
• {args} (`any?`)
• {...} (`any`)
Return: ~
(`any`)
(`integer`)
rpcrequest({channel}, {method} [, {args}...]) *rpcrequest()*
Sends a request to {channel} to invoke {method} via
@ -7999,7 +8005,7 @@ rpcrequest({channel}, {method} [, {args}...]) *rpcrequest()*
Parameters: ~
• {channel} (`integer`)
• {method} (`string`)
• {args} (`any?`)
• {...} (`any`)
Return: ~
(`any`)
@ -8031,7 +8037,7 @@ screenattr({row}, {col}) *screenattr()*
• {col} (`integer`)
Return: ~
(`any`)
(`integer`)
screenchar({row}, {col}) *screenchar()*
The result is a Number, which is the character at position
@ -8048,7 +8054,7 @@ screenchar({row}, {col}) *screenchar()*
• {col} (`integer`)
Return: ~
(`any`)
(`integer`)
screenchars({row}, {col}) *screenchars()*
The result is a |List| of Numbers. The first number is the same
@ -8062,7 +8068,7 @@ screenchars({row}, {col}) *screenchars()*
• {col} (`integer`)
Return: ~
(`any`)
(`integer[]`)
screencol() *screencol()*
The result is a Number, which is the current screen column of
@ -8080,7 +8086,7 @@ screencol() *screencol()*
<
Return: ~
(`any`)
(`integer[]`)
screenpos({winid}, {lnum}, {col}) *screenpos()*
The result is a Dict with the screen position of the text
@ -8123,7 +8129,7 @@ screenrow() *screenrow()*
Note: Same restrictions as with |screencol()|.
Return: ~
(`any`)
(`integer`)
screenstring({row}, {col}) *screenstring()*
The result is a String that contains the base character and
@ -8138,7 +8144,7 @@ screenstring({row}, {col}) *screenstring()*
• {col} (`integer`)
Return: ~
(`any`)
(`string`)
search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]]) *search()*
Search for regexp pattern {pattern}. The search starts at the
@ -8498,7 +8504,7 @@ searchpair({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {timeo
Parameters: ~
• {start} (`string`)
• {middle} (`string`)
• {end_} (`string`)
• {end} (`string`)
• {flags} (`string?`)
• {skip} (`string|function?`)
• {stopline} (`integer?`)
@ -8522,7 +8528,7 @@ searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline} [, {ti
Parameters: ~
• {start} (`string`)
• {middle} (`string`)
• {end_} (`string`)
• {end} (`string`)
• {flags} (`string?`)
• {skip} (`string|function?`)
• {stopline} (`integer?`)
@ -8565,7 +8571,7 @@ serverlist() *serverlist()*
<
Return: ~
(`any`)
(`string[]`)
serverstart([{address}]) *serverstart()*
Opens a socket or named pipe at {address} and listens for
@ -8605,7 +8611,7 @@ serverstart([{address}]) *serverstart()*
• {address} (`string?`)
Return: ~
(`any`)
(`string`)
serverstop({address}) *serverstop()*
Closes the pipe or socket at {address}.
@ -8617,7 +8623,7 @@ serverstop({address}) *serverstop()*
• {address} (`string`)
Return: ~
(`any`)
(`integer`)
setbufline({buf}, {lnum}, {text}) *setbufline()*
Set line {lnum} to {text} in buffer {buf}. This works like
@ -8650,7 +8656,7 @@ setbufline({buf}, {lnum}, {text}) *setbufline()*
• {text} (`string|string[]`)
Return: ~
(`any`)
(`integer`)
setbufvar({buf}, {varname}, {val}) *setbufvar()*
Set option or local variable {varname} in buffer {buf} to
@ -8770,7 +8776,7 @@ setcmdline({str} [, {pos}]) *setcmdline()*
• {pos} (`integer?`)
Return: ~
(`any`)
(`integer`)
setcmdpos({pos}) *setcmdpos()*
Set the cursor position in the command line to byte position
@ -9102,7 +9108,7 @@ setqflist({list} [, {action} [, {what}]]) *setqflist()*
• {what} (`vim.fn.setqflist.what?`)
Return: ~
(`any`)
(`integer`)
setreg({regname}, {value} [, {options}]) *setreg()*
Set the register {regname} to {value}.
@ -9273,7 +9279,7 @@ sha256({string}) *sha256()*
• {string} (`string`)
Return: ~
(`any`)
(`string`)
shellescape({string} [, {special}]) *shellescape()*
Escape {string} for use as a shell command argument.
@ -9312,7 +9318,7 @@ shellescape({string} [, {special}]) *shellescape()*
• {special} (`boolean?`)
Return: ~
(`any`)
(`string`)
shiftwidth([{col}]) *shiftwidth()*
Returns the effective value of 'shiftwidth'. This is the
@ -9790,7 +9796,7 @@ simplify({filename}) *simplify()*
• {filename} (`string`)
Return: ~
(`any`)
(`string`)
sin({expr}) *sin()*
Return the sine of {expr}, measured in radians, as a |Float|.
@ -9806,7 +9812,7 @@ sin({expr}) *sin()*
• {expr} (`number`)
Return: ~
(`any`)
(`number`)
sinh({expr}) *sinh()*
Return the hyperbolic sine of {expr} as a |Float| in the range
@ -9838,7 +9844,7 @@ slice({expr}, {start} [, {end}]) *slice()*
Parameters: ~
• {expr} (`any`)
• {start} (`integer`)
• {end_} (`integer?`)
• {end} (`integer?`)
Return: ~
(`any`)
@ -9950,12 +9956,12 @@ sort({list} [, {how} [, {dict}]]) *sort()* *E70
<
Parameters: ~
• {list} (`any`)
• {list} (`T[]`)
• {how} (`string|function?`)
• {dict} (`any?`)
Return: ~
(`any`)
(`T[]`)
soundfold({word}) *soundfold()*
Return the sound-folded equivalent of {word}. Uses the first
@ -9969,7 +9975,7 @@ soundfold({word}) *soundfold()*
• {word} (`string`)
Return: ~
(`any`)
(`string`)
spellbadword([{sentence}]) *spellbadword()*
Without argument: The result is the badly spelled word under
@ -10028,7 +10034,7 @@ spellsuggest({word} [, {max} [, {capital}]]) *spellsuggest()*
• {capital} (`boolean?`)
Return: ~
(`any`)
(`string[]`)
split({string} [, {pattern} [, {keepempty}]]) *split()*
Make a |List| out of {string}. When {pattern} is omitted or
@ -10061,7 +10067,7 @@ split({string} [, {pattern} [, {keepempty}]]) *split()*
• {keepempty} (`boolean?`)
Return: ~
(`any`)
(`string[]`)
sqrt({expr}) *sqrt()*
Return the non-negative square root of Float {expr} as a
@ -10232,6 +10238,7 @@ str2list({string} [, {utf8}]) *str2list()*
and exists only for backwards-compatibility.
With UTF-8 composing characters are handled properly: >vim
echo str2list("á") " returns [97, 769]
<
Parameters: ~
• {string} (`string`)
@ -11165,28 +11172,6 @@ tempname() *tempname()*
Return: ~
(`string`)
termopen({cmd} [, {opts}]) *termopen()*
Spawns {cmd} in a new pseudo-terminal session connected
to the current (unmodified) buffer. Parameters and behavior
are the same as |jobstart()| except "pty", "width", "height",
and "TERM" are ignored: "height" and "width" are taken from
the current window. Note that termopen() implies a "pty" arg
to jobstart(), and thus has the implications documented at
|jobstart()|.
Returns the same values as jobstart().
Terminal environment is initialized as in |jobstart-env|,
except $TERM is set to "xterm-256color". Full behavior is
described in |terminal|.
Parameters: ~
• {cmd} (`string|string[]`)
• {opts} (`table?`)
Return: ~
(`any`)
test_garbagecollect_now() *test_garbagecollect_now()*
Like |garbagecollect()|, but executed right away. This must
only be called directly to avoid any structure to exist
@ -11646,7 +11631,7 @@ virtcol2col({winid}, {lnum}, {col}) *virtcol2col()*
• {col} (`integer`)
Return: ~
(`any`)
(`integer`)
visualmode([{expr}]) *visualmode()*
The result is a String, which describes the last Visual mode
@ -11670,7 +11655,7 @@ visualmode([{expr}]) *visualmode()*
• {expr} (`boolean?`)
Return: ~
(`any`)
(`string`)
wait({timeout}, {condition} [, {interval}]) *wait()*
Waits until {condition} evaluates to |TRUE|, where {condition}
@ -11812,7 +11797,7 @@ win_id2win({expr}) *win_id2win()*
• {expr} (`integer`)
Return: ~
(`any`)
(`integer`)
win_move_separator({nr}, {offset}) *win_move_separator()*
Move window {nr}'s vertical separator (i.e., the right border)
@ -11989,7 +11974,7 @@ winlayout([{tabnr}]) *winlayout()*
• {tabnr} (`integer?`)
Return: ~
(`any`)
(`any[]`)
winline() *winline()*
The result is a Number, which is the screen line of the cursor
@ -12037,7 +12022,7 @@ winnr([{arg}]) *winnr()*
• {arg} (`string|integer?`)
Return: ~
(`any`)
(`integer`)
winrestcmd() *winrestcmd()*
Returns a sequence of |:resize| commands that should restore
@ -12051,7 +12036,7 @@ winrestcmd() *winrestcmd()*
<
Return: ~
(`any`)
(`string`)
winrestview({dict}) *winrestview()*
Uses the |Dictionary| returned by |winsaveview()| to restore
@ -12123,7 +12108,7 @@ winwidth({nr}) *winwidth()*
• {nr} (`integer`)
Return: ~
(`any`)
(`integer`)
wordcount() *wordcount()*
The result is a dictionary of byte/chars/word statistics for
@ -12213,11 +12198,11 @@ xor({expr}, {expr}) *xor()*
<
Parameters: ~
• {expr} (`number`)
• {expr1} (`number`)
• {expr} (`integer`)
• {expr1} (`integer`)
Return: ~
(`any`)
(`integer`)
==============================================================================
2. Matching a pattern in a String *string-match*

View File

@ -1443,18 +1443,17 @@ since formatting is highly dependent on the type of file. It makes
sense to use an |autoload| script, so the corresponding script is only loaded
when actually needed and the script should be called <filetype>format.vim.
For example, the XML filetype plugin distributed with Vim in the $VIMRUNTIME
directory, sets the 'formatexpr' option to: >
For example, the XML filetype plugin distributed with Vim in the
$VIMRUNTIME/ftplugin directory, sets the 'formatexpr' option to: >
setlocal formatexpr=xmlformat#Format()
That means, you will find the corresponding script, defining the
xmlformat#Format() function, in the directory:
`$VIMRUNTIME/autoload/xmlformat.vim`
xmlformat#Format() function, in the file `$VIMRUNTIME/autoload/xmlformat.vim`
Here is an example script that removes trailing whitespace from the selected
text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim: >
text. Put it in your autoload directory, e.g. ~/.vim/autoload/format.vim:
>vim
func! format#Format()
" only reformat on explicit gq command
if mode() != 'n'
@ -1487,7 +1486,7 @@ debugging it helps to set the 'debug' option.
*right-justify*
There is no command in Vim to right justify text. You can do it with
an external command, like "par" (e.g.: "!}par" to format until the end of the
an external command, like "par" (e.g.: `:.,}!par` to format until the end of the
paragraph) or set 'formatprg' to "par".
*format-comments*
@ -1553,7 +1552,7 @@ type of comment string. A part consists of:
some indent for the start or end part that can be removed.
When a string has none of the 'f', 's', 'm' or 'e' flags, Vim assumes the
comment string repeats at the start of each line. The flags field may be
comment string repeats at the start of each line. The {flags} field may be
empty.
Any blank space in the text before and after the {string} is part of the

View File

@ -20,8 +20,8 @@ There are several ways to open a channel:
2. Through stdin, stdout and stderr of a process spawned by |jobstart()|.
3. Through the PTY master end of a PTY opened with
`jobstart(..., {'pty': v:true})` or |termopen()|.
3. Through the PTY master end of a PTY opened with |nvim_open_term()| or
`jobstart(…, {'pty': v:true})`.
4. By connecting to a TCP/IP socket or named pipe with |sockconnect()|.

View File

@ -41,15 +41,19 @@ thus you cannot edit beyond that.
The command-lines that you enter are remembered in a history table. You can
recall them with the up and down cursor keys. There are actually five
history tables:
- one for ':' commands
- one for search strings
- one for expressions
- one for input lines, typed for the |input()| function.
- one for debug mode commands
These are completely separate. Each history can only be accessed when
entering the same type of line.
Use the 'history' option to set the number of lines that are remembered.
Notes:
- When you enter a command-line that is exactly the same as an older one, the
old one is removed (to avoid repeated commands moving older commands out of
the history).

View File

@ -1,11 +1,118 @@
*backers.txt* Nvim
*credits.txt* Nvim
NVIM REFERENCE MANUAL
==============================================================================
Fundraiser Backers
Credits *credits*
Most of Vim was written by Bram Moolenaar <Bram@vim.org> |Bram-Moolenaar|.
Parts of the documentation come from several Vi manuals, written by:
W.N. Joy
Alan P.W. Hewett
Mark Horton
The Vim editor is based on Stevie and includes (ideas from) other software,
worked on by the people mentioned here. Other people helped by sending me
patches, suggestions and giving feedback about what is good and bad in Vim.
Vim would never have become what it is now, without the help of these people!
Ron Aaron Win32 GUI changes
Mohsin Ahmed encryption
Zoltan Arpadffy work on VMS port
Tony Andrews Stevie
Gert van Antwerpen changes for DJGPP on MS-DOS
Berkeley DB(3) ideas for swap file implementation
Keith Bostic Nvi
Walter Briscoe Makefile updates, various patches
Ralf Brown SPAWNO library for MS-DOS
Robert Colon many useful remarks
Marcin Dalecki GTK+ GUI port, toolbar icons, gettext()
Kayhan Demirel sent me news in Uganda
Chris & John Downey xvi (ideas for multi-windows version)
Henk Elbers first VMS port
Daniel Elstner GTK+ 2 port
Eric Fischer Mac port, 'cindent', and other improvements
Benji Fisher Answering lots of user questions
Bill Foster Athena GUI port (later removed)
Google Let Bram work on Vim one day a week
Loic Grenie xvim (ideas for multi windows version)
Sven Guckes Vim promoter and previous WWW page maintainer
Darren Hiebert Exuberant ctags
Jason Hildebrand GTK+ 2 port
Bruce Hunsaker improvements for VMS port
Andy Kahn Cscope support, GTK+ GUI port
Oezguer Kesim Maintainer of Vim Mailing Lists
Axel Kielhorn work on the Macintosh port
Steve Kirkendall Elvis
Roger Knobbe original port to Windows NT
Sergey Laskavy Vim's help from Moscow
Felix von Leitner Previous maintainer of Vim Mailing Lists
David Leonard Port of Python extensions to Unix
Avner Lottem Edit in right-to-left windows
Flemming Madsen X11 client-server, various features and patches
Tony Mechelynck answers many user questions
Paul Moore Python interface extensions, many patches
Katsuhito Nagano Work on multibyte versions
Sung-Hyun Nam Work on multibyte versions
Vince Negri Win32 GUI and generic console enhancements
Steve Oualline Author of the first Vim book |frombook|
Dominique Pelle Valgrind reports and many fixes
A.Politz Many bug reports and some fixes
George V. Reilly Win32 port, Win32 GUI start-off
Stephen Riehm bug collector
Stefan Roemer various patches and help to users
Ralf Schandl IBM OS/390 port
Olaf Seibert DICE and BeBox version, regexp improvements
Mortaza Shiran Farsi patches
Peter da Silva termlib
Paul Slootman OS/2 port
Henry Spencer regular expressions
Dany St-Amant Macintosh port
Tim Thompson Stevie
G. R. (Fred) Walter Stevie
Sven Verdoolaege Perl interface
Robert Webb Command-line completion, GUI versions, and
lots of patches
Ingo Wilken Tcl interface
Mike Williams PostScript printing
Juergen Weigert Lattice version, AUX improvements, Unix and
MS-DOS ports, autoconf
Stefan 'Sec' Zehl Maintainer of vim.org
Yasuhiro Matsumoto many MS-Windows improvements
Ken Takata fixes and features
Kazunobu Kuriyama GTK 3
Christian Brabandt many fixes, features, user support, etc.
Yegappan Lakshmanan many quickfix features
I wish to thank all the people that sent me bug reports and suggestions. The
list is too long to mention them all here. Vim would not be the same without
the ideas from all these people: They keep Vim alive!
*love* *peace* *friendship* *gross-national-happiness*
Documentation may refer to other versions of Vi:
*Vi* *vi*
Vi "the original". Without further remarks this is the version
of Vi that appeared in Sun OS 4.x. ":version" returns
"Version 3.7, 6/7/85". Source code only available with a license.
*Nvi*
Nvi The "New" Vi. The version of Vi that comes with BSD 4.4 and FreeBSD.
Very good compatibility with the original Vi, with a few extensions.
The version used is 1.79. ":version" returns "Version 1.79
(10/23/96)". Source code is freely available.
*Elvis*
Elvis Another Vi clone, made by Steve Kirkendall. Very compact but isn't
as flexible as Vim. Source code is freely available.
Vim Nvim is based on Vim. https://www.vim.org/
==============================================================================
Neovim fundraiser backers *backers.txt*
Thank you to everyone who backed the original Neovim Fundraiser.

View File

@ -16,45 +16,34 @@ Deprecated features
DEPRECATED IN 0.11 *deprecated-0.11*
API
- nvim_subscribe() Plugins must maintain their own "multicast" channels list.
- nvim_unsubscribe() Plugins must maintain their own "multicast" channels list.
LUA
- vim.region() Use |getregionpos()| instead.
- *vim.highlight* Renamed to |vim.hl|.
- vim.validate(opts: table) Use form 1. See |vim.validate()|.
• nvim_subscribe() Plugins must maintain their own "multicast" channels list.
• nvim_unsubscribe() Plugins must maintain their own "multicast" channels list.
DIAGNOSTICS
- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
- *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count=-1, float=true}` instead.
- *vim.diagnostic.get_next_pos()*
Use the "lnum" and "col" fields from the return value of
|vim.diagnostic.get_next()| instead.
- *vim.diagnostic.get_prev_pos()*
Use the "lnum" and "col" fields from the return value of
|vim.diagnostic.get_prev()| instead.
- The "win_id" parameter used by various functions is deprecated in favor of
• *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
• *vim.diagnostic.goto_prev()* Use |vim.diagnostic.jump()| with `{count=-1, float=true}` instead.
• *vim.diagnostic.get_next_pos()* Use the "lnum" and "col" fields from the
return value of |vim.diagnostic.get_next()| instead.
• *vim.diagnostic.get_prev_pos()* Use the "lnum" and "col" fields from the
return value of |vim.diagnostic.get_prev()| instead.
• The "win_id" parameter used by various functions is deprecated in favor of
"winid" |winid|
- The "cursor_position" parameter of |vim.diagnostic.JumpOpts| is renamed to
"pos"
• |vim.diagnostic.JumpOpts| renamed its "cursor_position" field to "pos".
TREESITTER
• *TSNode:child_containing_descendant()* Use
|TSNode:child_with_descendant()| instead; it is identical except that it can
return the descendant itself.
HIGHLIGHTS
• *TermCursorNC* Unfocused |terminal| windows do not have a cursor.
LSP
• *vim.lsp.util.jump_to_location* Use |vim.lsp.util.show_document()| with
`{focus=true}` instead.
`{focus=true}` instead.
• *vim.lsp.buf.execute_command* Use |Client:exec_cmd()| instead.
• *vim.lsp.buf.completion* Use |vim.lsp.completion.trigger()| instead.
• vim.lsp.buf_request_all The `error` key has been renamed to `err` inside
the result parameter of the handler.
• *vim.lsp.with()* Pass configuration to equivalent
functions in `vim.lsp.buf.*`.
• |vim.lsp.handlers|
No longer support client to server response handlers. Only server to
client requests/notification handlers are supported.
• |vim.lsp.handlers| Does not support client-to-server response handlers. Only
supports server-to-client requests/notification handlers.
• *vim.lsp.handlers.signature_help()* Use |vim.lsp.buf.signature_help()| instead.
• `client.request()` Use |Client:request()| instead.
• `client.request_sync()` Use |Client:request_sync()| instead.
@ -64,6 +53,19 @@ LSP
• `client.is_stopped()` Use |Client:is_stopped()| instead.
• `client.supports_method()` Use |Client:supports_method()| instead.
• `client.on_attach()` Use |Client:on_attach()| instead.
• `vim.lsp.start_client()` Use |vim.lsp.start()| instead.
LUA
• vim.region() Use |getregionpos()| instead.
• *vim.highlight* Renamed to |vim.hl|.
• vim.validate(opts: table) Use form 1. See |vim.validate()|.
TREESITTER
• *TSNode:child_containing_descendant()* Use |TSNode:child_with_descendant()|
instead; it is identical except that it can return the descendant itself.
VIMSCRIPT
• *termopen()* Use |jobstart() with `{term: v:true}`.
------------------------------------------------------------------------------
DEPRECATED IN 0.10 *deprecated-0.10*
@ -125,198 +127,198 @@ TREESITTER
DEPRECATED IN 0.9 *deprecated-0.9*
API
- *nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
- *nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
*nvim_get_hl_by_name()* Use |nvim_get_hl()| instead.
*nvim_get_hl_by_id()* Use |nvim_get_hl()| instead.
TREESITTER
- *vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| instead.
- *vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| instead.
- *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()|
*vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| instead.
*vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| instead.
*vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()|
and |TSNode:type()| instead.
• The following top level Treesitter functions have been moved:
- *vim.treesitter.inspect_language()* -> |vim.treesitter.language.inspect()|
- *vim.treesitter.get_query_files()* -> |vim.treesitter.query.get_files()|
- *vim.treesitter.set_query()* -> |vim.treesitter.query.set()|
- *vim.treesitter.query.set_query()* -> |vim.treesitter.query.set()|
- *vim.treesitter.get_query()* -> |vim.treesitter.query.get()|
- *vim.treesitter.query.get_query()* -> |vim.treesitter.query.get()|
- *vim.treesitter.parse_query()* -> |vim.treesitter.query.parse()|
- *vim.treesitter.query.parse_query()* -> |vim.treesitter.query.parse()|
- *vim.treesitter.add_predicate()* -> |vim.treesitter.query.add_predicate()|
- *vim.treesitter.add_directive()* -> |vim.treesitter.query.add_directive()|
- *vim.treesitter.list_predicates()* -> |vim.treesitter.query.list_predicates()|
- *vim.treesitter.list_directives()* -> |vim.treesitter.query.list_directives()|
- *vim.treesitter.query.get_range()* -> |vim.treesitter.get_range()|
- *vim.treesitter.query.get_node_text()* -> |vim.treesitter.get_node_text()|
*vim.treesitter.inspect_language()* -> |vim.treesitter.language.inspect()|
*vim.treesitter.get_query_files()* -> |vim.treesitter.query.get_files()|
*vim.treesitter.set_query()* -> |vim.treesitter.query.set()|
*vim.treesitter.query.set_query()* -> |vim.treesitter.query.set()|
*vim.treesitter.get_query()* -> |vim.treesitter.query.get()|
*vim.treesitter.query.get_query()* -> |vim.treesitter.query.get()|
*vim.treesitter.parse_query()* -> |vim.treesitter.query.parse()|
*vim.treesitter.query.parse_query()* -> |vim.treesitter.query.parse()|
*vim.treesitter.add_predicate()* -> |vim.treesitter.query.add_predicate()|
*vim.treesitter.add_directive()* -> |vim.treesitter.query.add_directive()|
*vim.treesitter.list_predicates()* -> |vim.treesitter.query.list_predicates()|
*vim.treesitter.list_directives()* -> |vim.treesitter.query.list_directives()|
*vim.treesitter.query.get_range()* -> |vim.treesitter.get_range()|
*vim.treesitter.query.get_node_text()* -> |vim.treesitter.get_node_text()|
LUA
- *nvim_exec()* Use |nvim_exec2()| instead.
- *vim.pretty_print()* Use |vim.print()| instead.
*nvim_exec()* Use |nvim_exec2()| instead.
*vim.pretty_print()* Use |vim.print()| instead.
------------------------------------------------------------------------------
DEPRECATED IN 0.8 OR EARLIER
API
- *nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
- *nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
- *nvim_command_output()* Use |nvim_exec2()| instead.
- *nvim_execute_lua()* Use |nvim_exec_lua()| instead.
- *nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
*nvim_buf_clear_highlight()* Use |nvim_buf_clear_namespace()| instead.
*nvim_buf_set_virtual_text()* Use |nvim_buf_set_extmark()| instead.
*nvim_command_output()* Use |nvim_exec2()| instead.
*nvim_execute_lua()* Use |nvim_exec_lua()| instead.
*nvim_get_option_info()* Use |nvim_get_option_info2()| instead.
COMMANDS
- *:rv* *:rviminfo* Deprecated alias to |:rshada| command.
- *:wv* *:wviminfo* Deprecated alias to |:wshada| command.
*:rv* *:rviminfo* Deprecated alias to |:rshada| command.
*:wv* *:wviminfo* Deprecated alias to |:wshada| command.
ENVIRONMENT VARIABLES
- *$NVIM_LISTEN_ADDRESS*
- Deprecated way to:
- set the server name (use |--listen| or |serverstart()| instead)
- get the server name (use |v:servername| instead)
- detect a parent Nvim (use |$NVIM| instead)
- Ignored if --listen is given.
- Unset by |terminal| and |jobstart()| unless explicitly given by the "env"
*$NVIM_LISTEN_ADDRESS*
Deprecated way to:
set the server name (use |--listen| or |serverstart()| instead)
get the server name (use |v:servername| instead)
detect a parent Nvim (use |$NVIM| instead)
Ignored if --listen is given.
Unset by |terminal| and |jobstart()| unless explicitly given by the "env"
option. Example: >vim
call jobstart(['foo'], { 'env': { 'NVIM_LISTEN_ADDRESS': v:servername } })
<
EVENTS
- *BufCreate* Use |BufAdd| instead.
- *EncodingChanged* Never fired; 'encoding' is always "utf-8".
- *FileEncoding* Never fired; equivalent to |EncodingChanged|.
- *GUIEnter* Never fired; use |UIEnter| instead.
- *GUIFailed* Never fired.
*BufCreate* Use |BufAdd| instead.
*EncodingChanged* Never fired; 'encoding' is always "utf-8".
*FileEncoding* Never fired; equivalent to |EncodingChanged|.
*GUIEnter* Never fired; use |UIEnter| instead.
*GUIFailed* Never fired.
KEYCODES
- *<MouseDown>* Use <ScrollWheelUp> instead.
- *<MouseUp>* Use <ScrollWheelDown> instead.
FUNCTIONS
- *buffer_exists()* Obsolete name for |bufexists()|.
- *buffer_name()* Obsolete name for |bufname()|.
- *buffer_number()* Obsolete name for |bufnr()|.
- *file_readable()* Obsolete name for |filereadable()|.
- *highlight_exists()* Obsolete name for |hlexists()|.
- *highlightID()* Obsolete name for |hlID()|.
- *inputdialog()* Use |input()| instead.
- *jobclose()* Obsolete name for |chanclose()|
- *jobsend()* Obsolete name for |chansend()|
- *last_buffer_nr()* Obsolete name for bufnr("$").
- *rpcstart()* Use |jobstart()| with `{'rpc': v:true}` instead.
- *rpcstop()* Use |jobstop()| instead to stop any job, or
`chanclose(id, "rpc")` to close RPC communication
without stopping the job. Use chanclose(id) to close
any socket.
• *<MouseDown>* Use <ScrollWheelUp> instead.
• *<MouseUp>* Use <ScrollWheelDown> instead.
HIGHLIGHTS
- *hl-VertSplit* Use |hl-WinSeparator| instead.
• *hl-VertSplit* Use |hl-WinSeparator| instead.
LSP DIAGNOSTICS
For each of the functions below, use the corresponding function in
|vim.diagnostic| instead (unless otherwise noted). For example, use
|vim.diagnostic.get()| instead of |vim.lsp.diagnostic.get()|.
- *vim.lsp.diagnostic.clear()* Use |vim.diagnostic.hide()| instead.
- *vim.lsp.diagnostic.disable()* Use |vim.diagnostic.enable()| instead.
- *vim.lsp.diagnostic.display()* Use |vim.diagnostic.show()| instead.
- *vim.lsp.diagnostic.enable()*
- *vim.lsp.diagnostic.get()*
- *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead.
- *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead.
- *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead.
- *vim.lsp.diagnostic.get_next()*
- *vim.lsp.diagnostic.get_next_pos()*
- *vim.lsp.diagnostic.get_prev()*
- *vim.lsp.diagnostic.get_prev_pos()*
- *vim.lsp.diagnostic.get_virtual_text_chunks_for_line()* No replacement. Use
• *vim.lsp.diagnostic.clear()* Use |vim.diagnostic.hide()| instead.
• *vim.lsp.diagnostic.disable()* Use |vim.diagnostic.enable()| instead.
• *vim.lsp.diagnostic.display()* Use |vim.diagnostic.show()| instead.
• *vim.lsp.diagnostic.enable()*
• *vim.lsp.diagnostic.get()*
• *vim.lsp.diagnostic.get_all()* Use |vim.diagnostic.get()| instead.
• *vim.lsp.diagnostic.get_count()* Use |vim.diagnostic.count()| instead.
• *vim.lsp.diagnostic.get_line_diagnostics()* Use |vim.diagnostic.get()| instead.
*vim.lsp.diagnostic.get_next()*
*vim.lsp.diagnostic.get_next_pos()*
*vim.lsp.diagnostic.get_prev()*
*vim.lsp.diagnostic.get_prev_pos()*
*vim.lsp.diagnostic.get_virtual_text_chunks_for_line()* No replacement. Use
options provided by |vim.diagnostic.config()| to customize virtual text.
- *vim.lsp.diagnostic.goto_next()*
- *vim.lsp.diagnostic.goto_prev()*
- *vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
- *vim.lsp.diagnostic.reset()*
- *vim.lsp.diagnostic.save()* Use |vim.diagnostic.set()| instead.
- *vim.lsp.diagnostic.set_loclist()* Use |vim.diagnostic.setloclist()| instead.
- *vim.lsp.diagnostic.set_qflist()* Use |vim.diagnostic.setqflist()| instead.
- *vim.lsp.diagnostic.show_line_diagnostics()* Use |vim.diagnostic.open_float()| instead.
- *vim.lsp.diagnostic.show_position_diagnostics()* Use |vim.diagnostic.open_float()| instead.
*vim.lsp.diagnostic.goto_next()*
*vim.lsp.diagnostic.goto_prev()*
*vim.lsp.diagnostic.redraw()* Use |vim.diagnostic.show()| instead.
*vim.lsp.diagnostic.reset()*
*vim.lsp.diagnostic.save()* Use |vim.diagnostic.set()| instead.
*vim.lsp.diagnostic.set_loclist()* Use |vim.diagnostic.setloclist()| instead.
*vim.lsp.diagnostic.set_qflist()* Use |vim.diagnostic.setqflist()| instead.
*vim.lsp.diagnostic.show_line_diagnostics()* Use |vim.diagnostic.open_float()| instead.
*vim.lsp.diagnostic.show_position_diagnostics()* Use |vim.diagnostic.open_float()| instead.
The following are deprecated without replacement. These functions are moved
internally and are no longer exposed as part of the API. Instead, use
|vim.diagnostic.config()| and |vim.diagnostic.show()|.
- *vim.lsp.diagnostic.set_signs()*
- *vim.lsp.diagnostic.set_underline()*
- *vim.lsp.diagnostic.set_virtual_text()*
*vim.lsp.diagnostic.set_signs()*
*vim.lsp.diagnostic.set_underline()*
*vim.lsp.diagnostic.set_virtual_text()*
LSP FUNCTIONS
- *vim.lsp.buf.server_ready()*
*vim.lsp.buf.server_ready()*
Use |LspAttach| instead, depending on your use-case. "Server ready" is not
part of the LSP spec, so the Nvim LSP client cannot meaningfully implement
it. "Ready" is ambiguous because:
- Language servers may finish analyzing the workspace, but edits can always
Language servers may finish analyzing the workspace, but edits can always
re-trigger analysis/builds.
- Language servers can serve some requests even while processing changes.
- *vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
Language servers can serve some requests even while processing changes.
*vim.lsp.buf.range_code_action()* Use |vim.lsp.buf.code_action()| with
the `range` parameter.
- *vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.
- *vim.lsp.util.set_qflist()* Use |setqflist()| instead.
- *vim.lsp.util.set_loclist()* Use |setloclist()| instead.
- *vim.lsp.buf_get_clients()* Use |vim.lsp.get_clients()| with
*vim.lsp.util.diagnostics_to_items()* Use |vim.diagnostic.toqflist()| instead.
*vim.lsp.util.set_qflist()* Use |setqflist()| instead.
*vim.lsp.util.set_loclist()* Use |setloclist()| instead.
*vim.lsp.buf_get_clients()* Use |vim.lsp.get_clients()| with
{buffer=bufnr} instead.
- *vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
*vim.lsp.buf.formatting()* Use |vim.lsp.buf.format()| with
{async=true} instead.
- *vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
*vim.lsp.buf.formatting_sync()* Use |vim.lsp.buf.format()| with
{async=false} instead.
- *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
*vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()|
or |vim.lsp.buf.format()| instead.
LUA
- vim.register_keystroke_callback() Use |vim.on_key()| instead.
vim.register_keystroke_callback() Use |vim.on_key()| instead.
NORMAL COMMANDS
- *]f* *[f* Same as "gf".
*]f* *[f* Same as "gf".
OPTIONS
- *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
*cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
`<>` notation is always enabled.
- *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
- *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
- *'langnoremap'* Deprecated alias to 'nolangremap'.
- 'sessionoptions' Flags "unix", "slash" are ignored and always enabled.
- *'vi'*
- 'viewoptions' Flags "unix", "slash" are ignored and always enabled.
- *'viminfo'* Deprecated alias to 'shada' option.
- *'viminfofile'* Deprecated alias to 'shadafile' option.
- *'paste'* *'nopaste'* Just Paste It.™ The 'paste' option is obsolete:
*'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
*'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.
*'langnoremap'* Deprecated alias to 'nolangremap'.
'sessionoptions' Flags "unix", "slash" are ignored and always enabled.
*'vi'*
'viewoptions' Flags "unix", "slash" are ignored and always enabled.
*'viminfo'* Deprecated alias to 'shada' option.
*'viminfofile'* Deprecated alias to 'shadafile' option.
*'paste'* *'nopaste'* Just Paste It.™ The 'paste' option is obsolete:
|paste| is handled automatically when you paste text
using your terminal's or GUI's paste feature
(CTRL-SHIFT-v, CMD-v (macOS), middle-click, …).
Enables "paste mode":
- Disables mappings in Insert, Cmdline mode.
- Disables abbreviations.
- Resets 'autoindent' 'expandtab' 'revins' 'ruler'
Disables mappings in Insert, Cmdline mode.
Disables abbreviations.
Resets 'autoindent' 'expandtab' 'revins' 'ruler'
'showmatch' 'smartindent' 'smarttab' 'softtabstop'
'textwidth' 'wrapmargin'.
- Treats 'formatoptions' as empty.
- Disables the effect of these options:
- 'cindent'
- 'indentexpr'
- 'lisp'
Treats 'formatoptions' as empty.
Disables the effect of these options:
'cindent'
'indentexpr'
'lisp'
UI EXTENSIONS
- *ui-wildmenu* Use |ui-cmdline| with |ui-popupmenu| instead. Enabled
*ui-wildmenu* Use |ui-cmdline| with |ui-popupmenu| instead. Enabled
by the `ext_wildmenu` |ui-option|. Emits these events:
- `["wildmenu_show", items]`
- `["wildmenu_select", selected]`
- `["wildmenu_hide"]`
- *term_background* Unused. The terminal background color is now detected
`["wildmenu_show", items]`
`["wildmenu_select", selected]`
`["wildmenu_hide"]`
*term_background* Unused. The terminal background color is now detected
by the Nvim core directly instead of the TUI.
VARIABLES
- *b:terminal_job_pid* Use `jobpid(&channel)` instead.
- *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
- Lua: `vim.bo[bufnr].channel`
- Vimscript: `getbufvar(bufnr, '&channel')`
• *b:terminal_job_pid* Use `jobpid(&channel)` instead.
• *b:terminal_job_id* Use `&channel` instead. To access in non-current buffer:
• Lua: `vim.bo[bufnr].channel`
• Vimscript: `getbufvar(bufnr, '&channel')`
VIMSCRIPT
• *buffer_exists()* Obsolete name for |bufexists()|.
• *buffer_name()* Obsolete name for |bufname()|.
• *buffer_number()* Obsolete name for |bufnr()|.
• *file_readable()* Obsolete name for |filereadable()|.
• *highlight_exists()* Obsolete name for |hlexists()|.
• *highlightID()* Obsolete name for |hlID()|.
• *inputdialog()* Use |input()| instead.
• *jobclose()* Obsolete name for |chanclose()|
• *jobsend()* Obsolete name for |chansend()|
• *last_buffer_nr()* Obsolete name for bufnr("$").
• *rpcstart()* Use |jobstart()| with `{'rpc': v:true}` instead.
• *rpcstop()* Use |jobstop()| instead to stop any job, or
`chanclose(id, "rpc")` to close RPC communication
without stopping the job. Use chanclose(id) to close
any socket.
vim:noet:tw=78:ts=8:ft=help:norl:

View File

@ -46,11 +46,11 @@ Remember to bump NVIM_API_LEVEL if it wasn't already during this development
cycle.
Other references:
* |msgpack-rpc|
* |ui|
* https://github.com/neovim/neovim/pull/3246
* https://github.com/neovim/neovim/pull/18375
* https://github.com/neovim/neovim/pull/21605
- |msgpack-rpc|
- |ui|
- https://github.com/neovim/neovim/pull/3246
- https://github.com/neovim/neovim/pull/18375
- https://github.com/neovim/neovim/pull/21605

View File

@ -300,7 +300,7 @@ vim.paste in runtime/lua/vim/_editor.lua like this: >
--- @returns false if client should cancel the paste.
LUA STDLIB DESIGN GUIDELINES *dev-lua*
STDLIB DESIGN GUIDELINES *dev-lua*
See also |dev-naming|.
@ -337,7 +337,7 @@ preference):
way. Advantage is that propagation happens for free and it's harder to
accidentally swallow errors. (E.g. using
`uv_handle/pipe:write()` without checking return values is common.)
4. `on_error` parameter
4. `on_error` callback
- For async and "visitors" traversing a graph, where many errors may be
collected while work continues.
5. `vim.notify` (sometimes with optional `opts.silent` (async, visitors ^))
@ -434,7 +434,9 @@ Use existing common {verb} names (actions) if possible:
- eval: Evaluates an expression
- exec: Executes code, may return a result
- fmt: Formats
- get: Gets things (often by a query)
- get: Gets things. Two variants (overloads):
1. `get<T>(id: int): T` returns one item.
2. `get<T>(filter: dict): T[]` returns a list.
- inspect: Presents a high-level, often interactive, view
- is_enabled: Checks if functionality is enabled.
- open: Opens something (a buffer, window, …)

View File

@ -163,6 +163,33 @@ show a sign for the highest severity diagnostic on a given line: >lua
}
<
*diagnostic-loclist-example*
Whenever the |location-list| is opened, the following `show` handler will show
the most recent diagnostics: >lua
vim.diagnostic.handlers.loclist = {
show = function(_, _, _, opts)
-- Generally don't want it to open on every update
opts.loclist.open = opts.loclist.open or false
local winid = vim.api.nvim_get_current_win()
vim.diagnostic.setloclist(opts.loclist)
vim.api.nvim_set_current_win(winid)
end
}
<
The handler accepts the same options as |vim.diagnostic.setloclist()| and can be
configured using |vim.diagnostic.config()|: >lua
-- Open the location list on every diagnostic change (warnings/errors only).
vim.diagnostic.config({
loclist = {
open = true,
severity = { min = vim.diagnostic.severity.WARN },
}
})
<
==============================================================================
HIGHLIGHTS *diagnostic-highlights*
@ -847,7 +874,8 @@ setqflist({opts}) *vim.diagnostic.setqflist()*
• {open}? (`boolean`, default: `true`) Open quickfix list
after setting.
• {title}? (`string`) Title of quickfix list. Defaults to
"Diagnostics".
"Diagnostics". If there's already a quickfix list with this
title, it's updated. If not, a new quickfix list is created.
• {severity}? (`vim.diagnostic.SeverityFilter`) See
|diagnostic-severity|.

View File

@ -597,7 +597,7 @@ To disable this behavior, set the following variable in your vimrc: >
let g:gdscript_recommended_style = 0
GIT COMMIT *ft-gitcommit-plugin*
GIT COMMIT *ft-gitcommit-plugin*
One command, :DiffGitCached, is provided to show a diff of the current commit
in the preview window. It is equivalent to calling "git diff --cached" plus
@ -778,7 +778,7 @@ An alternative to using `MANPAGER` in shell can be redefined `man`, for example:
nvim "+hide Man $1"
}
MARKDOWN *ft-markdown-plugin*
MARKDOWN *ft-markdown-plugin*
To enable folding use this: >
let g:markdown_folding = 1
@ -870,7 +870,7 @@ To enable this behavior, set the following variable in your vimrc: >
let g:rst_style = 1
RNOWEB *ft-rnoweb-plugin*
RNOWEB *ft-rnoweb-plugin*
The 'formatexpr' option is set dynamically with different values for R code
and for LaTeX code. If you prefer that 'formatexpr' is not set, add to your

View File

@ -82,9 +82,11 @@ The most efficient is to call a function without arguments: >
The function must use v:lnum. See |expr-option-function|.
These are the conditions with which the expression is evaluated:
- The current buffer and window are set for the line.
- The variable "v:lnum" is set to the line number.
- The result is used for the fold level in this way:
The result of foldexpr then determines the fold level as follows:
value meaning ~
0 the line is not in a fold
1, 2, .. the line is in a fold with this level
@ -99,6 +101,8 @@ These are the conditions with which the expression is evaluated:
"<1", "<2", .. a fold with this level ends at this line
">1", ">2", .. a fold with this level starts at this line
The result values "=", "s" and "a" are more expensive, please see |fold-expr-slow|.
It is not required to mark the start (end) of a fold with ">1" ("<1"), a fold
will also start (end) when the fold level is higher (lower) than the fold
level of the previous line.
@ -112,12 +116,6 @@ recognized, there is no error message and the fold level will be zero.
For debugging the 'debug' option can be set to "msg", the error messages will
be visible then.
Note: Since the expression has to be evaluated for every line, this fold
method can be very slow!
Try to avoid the "=", "a" and "s" return values, since Vim often has to search
backwards for a line for which the fold level is defined. This can be slow.
If the 'foldexpr' expression starts with s: or |<SID>|, then it is replaced
with the script ID (|local-function|). Examples: >
set foldexpr=s:MyFoldExpr()
@ -143,6 +141,35 @@ end in that line.
It may happen that folds are not updated properly. You can use |zx| or |zX|
to force updating folds.
Minimizing Computational Cost *fold-expr-slow*
Due to its computational cost, this fold method can make Vim unresponsive,
especially when the fold level of all lines have to be initially computed.
Afterwards, after each change, Vim restricts the computation of foldlevels
to those lines whose fold level was affected by it (and reuses the known
foldlevels of all the others).
The fold expression should therefore strive to minimize the number of dependent
lines needed for the computation of a given line: For example, try to avoid the
"=", "a" and "s" return values, because these will require the evaluation of the
fold levels on previous lines until an independent fold level is found.
If this proves difficult, the next best thing could be to cache all fold levels
in a buffer-local variable (b:foldlevels) that is only updated on |b:changedtick|:
>vim
func MyFoldFunc()
if b:lasttick == b:changedtick
return b:foldlevels[v:lnum - 1]
endif
let b:lasttick = b:changedtick
let b:foldlevels = []
" compute foldlevels ...
return b:foldlevels[v:lnum - 1]
enddef
set foldexpr=s:MyFoldFunc()
<
In above example further speedup was gained by using a function without
arguments (that must still use v:lnum). See |expr-option-function|.
SYNTAX *fold-syntax*

View File

@ -1,10 +1,10 @@
*gui.txt* Nvim
VIM REFERENCE MANUAL by Bram Moolenaar
VIM REFERENCE MANUAL by Bram Moolenaar
Nvim Graphical User Interface *gui* *GUI*
Nvim Graphical User Interface *gui* *GUI*
Any client that supports the Nvim |ui-protocol| can be used as a UI for Nvim.
And multiple UIs can connect to the same Nvim instance! The terms "UI" and
@ -20,8 +20,9 @@ features, whereas help tags with the "ui-" prefix refer to the |ui-protocol|.
Nvim provides a default, builtin UI (the |TUI|), but there are many other
(third-party) GUIs that you can use instead:
- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
*vscode*
- vscode-neovim (Nvim in VSCode!) https://github.com/vscode-neovim/vscode-neovim
- Firenvim (Nvim in your web browser!) https://github.com/glacambre/firenvim
- Neovide https://neovide.dev/
- Goneovim https://github.com/akiyosi/goneovim
- Nvy https://github.com/RMichelsen/Nvy
@ -32,71 +33,71 @@ Nvim provides a default, builtin UI (the |TUI|), but there are many other
Type |gO| to see the table of contents.
==============================================================================
Starting the GUI *gui-config* *gui-start*
Starting the GUI *gui-config* *gui-start*
*ginit.vim* *gui-init* *gvimrc* *$MYGVIMRC*
*ginit.vim* *gui-init* *gvimrc* *$MYGVIMRC*
For GUI-specific configuration Nvim provides the |UIEnter| event. This
happens after other |initialization|s, or whenever a UI attaches (multiple UIs
can connect to any Nvim instance).
Example: this sets "g:gui" to the value of the UI's "rgb" field: >
:autocmd UIEnter * let g:gui = filter(nvim_list_uis(),{k,v-> v.chan==v:event.chan})[0].rgb
:autocmd UIEnter * let g:gui = filter(nvim_list_uis(),{k,v-> v.chan==v:event.chan})[0].rgb
<
*:winp* *:winpos* *E188*
*:winp* *:winpos* *E188*
:winp[os]
Display current position of the top left corner of the GUI vim
window in pixels. Does not work in all versions.
Also see |getwinpos()|, |getwinposx()| and |getwinposy()|.
Display current position of the top left corner of the GUI vim
window in pixels. Does not work in all versions.
Also see |getwinpos()|, |getwinposx()| and |getwinposy()|.
:winp[os] {X} {Y} *E466*
Put the GUI vim window at the given {X} and {Y} coordinates.
The coordinates should specify the position in pixels of the
top left corner of the window.
When the GUI window has not been opened yet, the values are
remembered until the window is opened. The position is
adjusted to make the window fit on the screen (if possible).
:winp[os] {X} {Y} *E466*
Put the GUI vim window at the given {X} and {Y} coordinates.
The coordinates should specify the position in pixels of the
top left corner of the window.
When the GUI window has not been opened yet, the values are
remembered until the window is opened. The position is
adjusted to make the window fit on the screen (if possible).
*:wi* *:win* *:winsize* *E465*
*:wi* *:win* *:winsize* *E465*
:win[size] {width} {height}
Set the window height to {width} by {height} characters.
Obsolete, use ":set lines=11 columns=22".
Set the window height to {width} by {height} characters.
Obsolete, use ":set lines=11 columns=22".
==============================================================================
Scrollbars *gui-scrollbars*
Scrollbars *gui-scrollbars*
There are vertical scrollbars and a horizontal scrollbar. You may
configure which ones appear with the 'guioptions' option.
The interface looks like this (with `:set guioptions=mlrb`):
>
+------------------------------+ `
| File Edit Help | <- Menu bar (m) `
+-+--------------------------+-+ `
|^| |^| `
|#| Text area. |#| `
| | | | `
|v|__________________________|v| `
Normal status line -> |-+ File.c 5,2 +-| `
+------------------------------+ `
| File Edit Help | <- Menu bar (m) `
+-+--------------------------+-+ `
|^| |^| `
|#| Text area. |#| `
| | | | `
|v|__________________________|v| `
Normal status line -> |-+ File.c 5,2 +-| `
between Vim windows |^|""""""""""""""""""""""""""|^| `
| | | | `
| | Another file buffer. | | `
| | | | `
|#| |#| `
Left scrollbar (l) -> |#| |#| <- Right `
|#| |#| scrollbar (r) `
| | | | `
|v| |v| `
+-+--------------------------+-+ `
| |< #### >| | <- Bottom `
+-+--------------------------+-+ scrollbar (b) `
| | | | `
| | Another file buffer. | | `
| | | | `
|#| |#| `
Left scrollbar (l) -> |#| |#| <- Right `
|#| |#| scrollbar (r) `
| | | | `
|v| |v| `
+-+--------------------------+-+ `
| |< #### >| | <- Bottom `
+-+--------------------------+-+ scrollbar (b) `
<
Any of the scrollbar or menu components may be turned off by not putting the
appropriate letter in the 'guioptions' string. The bottom scrollbar is
only useful when 'nowrap' is set.
VERTICAL SCROLLBARS *gui-vert-scroll*
VERTICAL SCROLLBARS *gui-vert-scroll*
Each Vim window has a scrollbar next to it which may be scrolled up and down
to move through the text in that buffer. The size of the scrollbar-thumb
@ -115,7 +116,7 @@ is on the left half, the right scrollbar column will contain scrollbars for
the rightmost windows. The same happens on the other side.
HORIZONTAL SCROLLBARS *gui-horiz-scroll*
HORIZONTAL SCROLLBARS *gui-horiz-scroll*
The horizontal scrollbar (at the bottom of the Vim GUI) may be used to
scroll text sideways when the 'wrap' option is turned off. The
@ -131,7 +132,7 @@ include the 'h' flag in 'guioptions'. Then the scrolling is limited by the
text of the current cursor line.
==============================================================================
Drag and drop *drag-n-drop*
Drag and drop *drag-n-drop*
You can drag and drop one or more files into the Vim window, where they will
be opened as if a |:drop| command was used.
@ -150,12 +151,12 @@ names with any Ex command. Special characters (space, tab, double quote and
"|"; backslash on non-MS-Windows systems) will be escaped.
==============================================================================
Menus *menus*
Menus *menus*
For an introduction see |usr_42.txt| in the user manual.
Using Menus *using-menus*
Using Menus *using-menus*
Basically, menus can be used just like mappings. You can define your own
menus, as many as you like.
@ -165,45 +166,45 @@ what the key sequence was.
For creating menus in a different language, see |:menutrans|.
*menu.vim*
*menu.vim*
The default menus are read from the file "$VIMRUNTIME/menu.vim". See
|$VIMRUNTIME| for where the path comes from. You can set up your own menus.
Starting off with the default set is a good idea. You can add more items, or,
if you don't like the defaults at all, start with removing all menus
|:unmenu-all|. You can also avoid the default menus being loaded by adding
this line to your vimrc file (NOT your gvimrc file!): >
:let did_install_default_menus = 1
:let did_install_default_menus = 1
If you also want to avoid the Syntax menu: >
:let did_install_syntax_menu = 1
:let did_install_syntax_menu = 1
The first item in the Syntax menu can be used to show all available filetypes
in the menu (which can take a bit of time to load). If you want to have all
filetypes already present at startup, add: >
:let do_syntax_sel_menu = 1
:let do_syntax_sel_menu = 1
Note that the menu.vim is sourced when `:syntax on` or `:filetype on` is
executed or after your .vimrc file is sourced. This means that the 'encoding'
option and the language of messages (`:language messages`) must be set before
that (if you want to change them).
*console-menus*
*console-menus*
Although this documentation is in the GUI section, you can actually use menus
in console mode too. You will have to load |menu.vim| explicitly then, it is
not done by default. You can use the |:emenu| command and command-line
completion with 'wildmenu' to access the menu entries almost like a real menu
system. To do this, put these commands in your vimrc file: >
:source $VIMRUNTIME/menu.vim
:set wildmenu
:set cpo-=<
:set wcm=<C-Z>
:map <F4> :emenu <C-Z>
:source $VIMRUNTIME/menu.vim
:set wildmenu
:set cpo-=<
:set wcm=<C-Z>
:map <F4> :emenu <C-Z>
Pressing <F4> will start the menu. You can now use the cursor keys to select
a menu entry. Hit <Enter> to execute it. Hit <Esc> if you want to cancel.
Creating New Menus *creating-menus*
Creating New Menus *creating-menus*
*:me* *:menu* *:noreme* *:noremenu*
*E330* *E327* *E331* *E336* *E333*
*E328* *E329* *E337* *E792*
*:me* *:menu* *:noreme* *:noremenu*
*E330* *E327* *E331* *E336* *E333*
*E328* *E329* *E337* *E792*
To create a new menu item, use the ":menu" commands. They are mostly like
the ":map" set of commands (see |map-modes|), but the first argument is a menu
item name, given as a path of menus and submenus with a '.' between them,
@ -224,15 +225,16 @@ tooltips for menus. See |terminal-input|.
Special characters in a menu name:
*menu-shortcut*
& The next character is the shortcut key. Make sure each
shortcut key is only used once in a (sub)menu. If you want to
insert a literal "&" in the menu name use "&&".
*menu-text*
<Tab> Separates the menu name from right-aligned text. This can be
used to show the equivalent typed command. The text "<Tab>"
can be used here for convenience. If you are using a real
tab, don't forget to put a backslash before it!
*menu-shortcut*
- & The next character is the shortcut key. Make sure each shortcut key is
only used once in a (sub)menu. If you want to insert a literal "&" in the
menu name use "&&".
*menu-text*
- <Tab> Separates the menu name from right-aligned text. This can be used to
show the equivalent typed command. The text "<Tab>" can be used here for
convenience. If you are using a real tab, don't forget to put a backslash
before it!
Example: >
:amenu &File.&Open<Tab>:e :browse e<CR>
@ -242,99 +244,99 @@ With the shortcut "F" (while keeping the <Alt> key pressed), and then "O",
this menu can be used. The second part is shown as "Open :e". The ":e"
is right aligned, and the "O" is underlined, to indicate it is the shortcut.
*:am* *:amenu* *:an* *:anoremenu*
*:am* *:amenu* *:an* *:anoremenu*
The ":amenu" command can be used to define menu entries for all modes at once,
except for Terminal mode. To make the command work correctly, a character is
automatically inserted for some modes:
mode inserted appended ~
Normal nothing nothing
Visual <C-C> <C-\><C-G>
Insert <C-\><C-O>
Cmdline <C-C> <C-\><C-G>
Op-pending <C-C> <C-\><C-G>
automatically inserted for some modes: >
mode inserted appended
Normal nothing nothing
Visual <C-C> <C-\><C-G>
Insert <C-\><C-O>
Cmdline <C-C> <C-\><C-G>
Op-pending <C-C> <C-\><C-G>
<
Example: >
:amenu File.Next :next^M
:amenu File.Next :next^M
is equal to: >
:nmenu File.Next :next^M
:vmenu File.Next ^C:next^M^\^G
:imenu File.Next ^\^O:next^M
:cmenu File.Next ^C:next^M^\^G
:omenu File.Next ^C:next^M^\^G
:nmenu File.Next :next^M
:vmenu File.Next ^C:next^M^\^G
:imenu File.Next ^\^O:next^M
:cmenu File.Next ^C:next^M^\^G
:omenu File.Next ^C:next^M^\^G
Careful: In Insert mode this only works for a SINGLE Normal mode command,
because of the CTRL-O. If you have two or more commands, you will need to use
the ":imenu" command. For inserting text in any mode, you can use the
expression register: >
:amenu Insert.foobar "='foobar'<CR>P
:amenu Insert.foobar "='foobar'<CR>P
The special text <Cmd> begins a "command menu", it executes the command
directly without changing modes. Where you might use ":...<CR>" you can
instead use "<Cmd>...<CR>". See |<Cmd>| for more info. Example: >
anoremenu File.Next <Cmd>next<CR>
anoremenu File.Next <Cmd>next<CR>
Note that <Esc> in Cmdline mode executes the command, like in a mapping. This
is Vi compatible. Use CTRL-C to quit Cmdline mode.
*:nme* *:nmenu* *:nnoreme* *:nnoremenu* *:nunme* *:nunmenu*
*:nme* *:nmenu* *:nnoreme* *:nnoremenu* *:nunme* *:nunmenu*
Menu commands starting with "n" work in Normal mode. |mapmode-n|
*:ome* *:omenu* *:onoreme* *:onoremenu* *:ounme* *:ounmenu*
*:ome* *:omenu* *:onoreme* *:onoremenu* *:ounme* *:ounmenu*
Menu commands starting with "o" work in Operator-pending mode. |mapmode-o|
*:vme* *:vmenu* *:vnoreme* *:vnoremenu* *:vunme* *:vunmenu*
*:vme* *:vmenu* *:vnoreme* *:vnoremenu* *:vunme* *:vunmenu*
Menu commands starting with "v" work in Visual mode. |mapmode-v|
*:xme* *:xmenu* *:xnoreme* *:xnoremenu* *:xunme* *:xunmenu*
*:xme* *:xmenu* *:xnoreme* *:xnoremenu* *:xunme* *:xunmenu*
Menu commands starting with "x" work in Visual and Select mode. |mapmode-x|
*:sme* *:smenu* *:snoreme* *:snoremenu* *:sunme* *:sunmenu*
*:sme* *:smenu* *:snoreme* *:snoremenu* *:sunme* *:sunmenu*
Menu commands starting with "s" work in Select mode. |mapmode-s|
*:ime* *:imenu* *:inoreme* *:inoremenu* *:iunme* *:iunmenu*
*:ime* *:imenu* *:inoreme* *:inoremenu* *:iunme* *:iunmenu*
Menu commands starting with "i" work in Insert mode. |mapmode-i|
*:cme* *:cmenu* *:cnoreme* *:cnoremenu* *:cunme* *:cunmenu*
*:cme* *:cmenu* *:cnoreme* *:cnoremenu* *:cunme* *:cunmenu*
Menu commands starting with "c" work in Cmdline mode. |mapmode-c|
*:tlm* *:tlmenu* *:tln* *:tlnoremenu* *:tlu* *:tlunmenu*
*:tlm* *:tlmenu* *:tln* *:tlnoremenu* *:tlu* *:tlunmenu*
Menu commands starting with "tl" work in Terminal mode. |mapmode-t|
*:menu-<silent>* *:menu-silent*
*:menu-<silent>* *:menu-silent*
To define a menu which will not be echoed on the command line, add
"<silent>" as the first argument. Example: >
:menu <silent> Settings.Ignore\ case :set ic<CR>
:menu <silent> Settings.Ignore\ case :set ic<CR>
The ":set ic" will not be echoed when using this menu. Messages from the
executed command are still given though. To shut them up too, add a ":silent"
in the executed command: >
:menu <silent> Search.Header :exe ":silent normal /Header\r"<CR>
:menu <silent> Search.Header :exe ":silent normal /Header\r"<CR>
"<silent>" may also appear just after "<script>".
*:menu-<script>* *:menu-script*
*:menu-<script>* *:menu-script*
The "to" part of the menu will be inspected for mappings. If you don't want
this, use the ":noremenu" command (or the similar one for a specific mode).
If you do want to use script-local mappings, add "<script>" as the very first
argument to the ":menu" command or just after "<silent>".
*menu-priority*
*menu-priority*
You can give a priority to a menu. Menus with a higher priority go more to
the right. The priority is given as a number before the ":menu" command.
Example: >
:80menu Buffer.next :bn<CR>
The default menus have these priorities:
File 10
Edit 20
Tools 40
Syntax 50
Buffers 60
Window 70
Help 9999
:80menu Buffer.next :bn<CR>
The default menus have these priorities: >
File 10
Edit 20
Tools 40
Syntax 50
Buffers 60
Window 70
Help 9999
<
When no or zero priority is given, 500 is used.
The priority for the PopUp menu is not used.
@ -342,18 +344,18 @@ You can use a priority higher than 9999, to make it go after the Help menu,
but that is non-standard and is discouraged. The highest possible priority is
about 32000. The lowest is 1.
*sub-menu-priority*
*sub-menu-priority*
The same mechanism can be used to position a sub-menu. The priority is then
given as a dot-separated list of priorities, before the menu name: >
:menu 80.500 Buffer.next :bn<CR>
:menu 80.500 Buffer.next :bn<CR>
Giving the sub-menu priority is only needed when the item is not to be put
in a normal position. For example, to put a sub-menu before the other items: >
:menu 80.100 Buffer.first :brew<CR>
:menu 80.100 Buffer.first :brew<CR>
Or to put a sub-menu after the other items, and further items with default
priority will be put before it: >
:menu 80.900 Buffer.last :blast<CR>
:menu 80.900 Buffer.last :blast<CR>
When a number is missing, the default value 500 will be used: >
:menu .900 myMenu.test :echo "text"<CR>
:menu .900 myMenu.test :echo "text"<CR>
The menu priority is only used when creating a new menu. When it already
existed, e.g., in another mode, the priority will not change. Thus, the
priority only needs to be given the first time a menu is used.
@ -363,49 +365,49 @@ menus can be different. This is different from menu-bar menus, which have
the same order for all modes.
NOTE: sub-menu priorities currently don't work for all versions of the GUI.
*menu-separator* *E332*
*menu-separator* *E332*
Menu items can be separated by a special item that inserts some space between
items. Depending on the system this is displayed as a line or a dotted line.
These items must start with a '-' and end in a '-'. The part in between is
used to give it a unique name. Priorities can be used as with normal items.
Example: >
:menu Example.item1 :do something
:menu Example.-Sep- :
:menu Example.item2 :do something different
:menu Example.item1 :do something
:menu Example.-Sep- :
:menu Example.item2 :do something different
Note that the separator also requires a rhs. It doesn't matter what it is,
because the item will never be selected. Use a single colon to keep it
simple.
*gui-toolbar*
*gui-toolbar*
The default toolbar is setup in menu.vim. The display of the toolbar is
controlled by the 'guioptions' letter 'T'. You can thus have menu & toolbar
together, or either on its own, or neither. The appearance is controlled by
the 'toolbar' option. You can choose between an image, text or both.
*toolbar-icon*
*toolbar-icon*
The toolbar is defined as a special menu called ToolBar, which only has one
level. Vim interprets the items in this menu as follows:
1) If an "icon=" argument was specified, the file with this name is used.
- 1 If an "icon=" argument was specified, the file with this name is used.
The file can either be specified with the full path or with the base name.
In the last case it is searched for in the "bitmaps" directory in
'runtimepath', like in point 3. Examples: >
:amenu icon=/usr/local/pixmaps/foo_icon.xpm ToolBar.Foo :echo "Foo"<CR>
:amenu icon=FooIcon ToolBar.Foo :echo "Foo"<CR>
:amenu icon=/usr/local/pixmaps/foo_icon.xpm ToolBar.Foo :echo "Foo"<CR>
:amenu icon=FooIcon ToolBar.Foo :echo "Foo"<CR>
< Note that in the first case the extension is included, while in the second
case it is omitted.
If the file cannot be opened the next points are tried.
A space in the file name must be escaped with a backslash.
A menu priority must come _after_ the icon argument: >
:amenu icon=foo 1.42 ToolBar.Foo :echo "42!"<CR>
2) An item called 'BuiltIn##', where ## is a number, is taken as number ## of
:amenu icon=foo 1.42 ToolBar.Foo :echo "42!"<CR>
- 2 An item called 'BuiltIn##', where ## is a number, is taken as number ## of
the built-in bitmaps available in Vim. Currently there are 31 numbered
from 0 to 30 which cover most common editing operations |builtin-tools|. >
:amenu ToolBar.BuiltIn22 :call SearchNext("back")<CR>
3) An item with another name is first searched for in the directory
:amenu ToolBar.BuiltIn22 :call SearchNext("back")<CR>
- 3 An item with another name is first searched for in the directory
"bitmaps" in 'runtimepath'. If found, the bitmap file is used as the
toolbar button image. Note that the exact filename is OS-specific: For
example, under Win32 the command >
:amenu ToolBar.Hello :echo "hello"<CR>
:amenu ToolBar.Hello :echo "hello"<CR>
< would find the file 'hello.bmp'. Under X11 it is 'Hello.xpm'.
For MS-Windows and the bitmap is scaled to fit the button. For
MS-Windows a size of 18 by 18 pixels works best.
@ -413,55 +415,56 @@ level. Vim interprets the items in this menu as follows:
The light grey pixels will be changed to the Window frame color and the
dark grey pixels to the window shadow color. More colors might also work,
depending on your system.
4) If the bitmap is still not found, Vim checks for a match against its list
- 4 If the bitmap is still not found, Vim checks for a match against its list
of built-in names. Each built-in button image has a name.
So the command >
:amenu ToolBar.Open :e
:amenu ToolBar.Open :e
< will show the built-in "open a file" button image if no open.bmp exists.
All the built-in names can be seen used in menu.vim.
5) If all else fails, a blank, but functioning, button is displayed.
- 5 If all else fails, a blank, but functioning, button is displayed.
*builtin-tools*
nr Name Normal action ~
00 New open new window
01 Open browse for file to open in current window
02 Save write buffer to file
03 Undo undo last change
04 Redo redo last undone change
05 Cut delete selected text to clipboard
06 Copy copy selected text to clipboard
07 Paste paste text from clipboard
08 Print print current buffer
09 Help open a buffer on Vim's builtin help
10 Find start a search command
11 SaveAll write all modified buffers to file
12 SaveSesn write session file for current situation
13 NewSesn write new session file
14 LoadSesn load session file
15 RunScript browse for file to run as a Vim script
16 Replace prompt for substitute command
17 WinClose close current window
18 WinMax make current window use many lines
19 WinMin make current window use few lines
20 WinSplit split current window
21 Shell start a shell
22 FindPrev search again, backward
23 FindNext search again, forward
24 FindHelp prompt for word to search help for
25 Make run make and jump to first error
26 TagJump jump to tag under the cursor
27 RunCtags build tags for files in current directory
28 WinVSplit split current window vertically
29 WinMaxWidth make current window use many columns
30 WinMinWidth make current window use few columns
*hidden-menus* *win32-hidden-menus*
*builtin-tools*
>
nr Name Normal action
00 New open new window
01 Open browse for file to open in current window
02 Save write buffer to file
03 Undo undo last change
04 Redo redo last undone change
05 Cut delete selected text to clipboard
06 Copy copy selected text to clipboard
07 Paste paste text from clipboard
08 Print print current buffer
09 Help open a buffer on Vim's builtin help
10 Find start a search command
11 SaveAll write all modified buffers to file
12 SaveSesn write session file for current situation
13 NewSesn write new session file
14 LoadSesn load session file
15 RunScript browse for file to run as a Vim script
16 Replace prompt for substitute command
17 WinClose close current window
18 WinMax make current window use many lines
19 WinMin make current window use few lines
20 WinSplit split current window
21 Shell start a shell
22 FindPrev search again, backward
23 FindNext search again, forward
24 FindHelp prompt for word to search help for
25 Make run make and jump to first error
26 TagJump jump to tag under the cursor
27 RunCtags build tags for files in current directory
28 WinVSplit split current window vertically
29 WinMaxWidth make current window use many columns
30 WinMinWidth make current window use few columns
<
*hidden-menus* *win32-hidden-menus*
In the Win32 GUI, starting a menu name with ']' excludes that menu from the
main menu bar. You must then use the |:popup| command to display it.
When splitting the window the window toolbar is not copied to the new window.
*popup-menu*
*popup-menu*
You can define the special menu "PopUp". This is the menu that is displayed
when the right mouse button is pressed, if 'mousemodel' is set to popup or
popup_setpos.
@ -483,7 +486,7 @@ The default "PopUp" menu is: >vim
anoremenu PopUp.How-to\ disable\ mouse <Cmd>help disable-mouse<CR>
<
Showing What Menus Are Mapped To *showing-menus*
Showing What Menus Are Mapped To *showing-menus*
To see what an existing menu is mapped to, use just one argument after the
menu commands (just like you would with the ":map" commands). If the menu
@ -502,25 +505,25 @@ Note that hitting <Tab> while entering a menu name after a menu command may
be used to complete the name of the menu item.
Executing Menus *execute-menus*
Executing Menus *execute-menus*
*:em* *:emenu* *E334* *E335*
:[range]em[enu] {menu} Execute {menu} from the command line.
The default is to execute the Normal mode
menu. If a range is specified, it executes
the Visual mode menu.
If used from <c-o>, it executes the
insert-mode menu Eg: >
:emenu File.Exit
*:em* *:emenu* *E334* *E335*
:[range]em[enu] {menu} Execute {menu} from the command line.
The default is to execute the Normal mode
menu. If a range is specified, it executes
the Visual mode menu.
If used from <c-o>, it executes the
insert-mode menu Eg: >
:emenu File.Exit
:[range]em[enu] {mode} {menu} Like above, but execute the menu for {mode}:
'n': |:nmenu| Normal mode
'v': |:vmenu| Visual mode
's': |:smenu| Select mode
'o': |:omenu| Operator-pending mode
't': |:tlmenu| Terminal mode
'i': |:imenu| Insert mode
'c': |:cmenu| Cmdline mode
:[range]em[enu] {mode} {menu} Like above, but execute the menu for {mode}:
- 'n': |:nmenu| Normal mode
- 'v': |:vmenu| Visual mode
- 's': |:smenu| Select mode
- 'o': |:omenu| Operator-pending mode
- 't': |:tlmenu| Terminal mode
- 'i': |:imenu| Insert mode
- 'c': |:cmenu| Cmdline mode
You can use :emenu to access useful menu items you may have got used to from
@ -531,10 +534,10 @@ When using a range, if the lines match with '<,'>, then the menu is executed
using the last visual selection.
Deleting Menus *delete-menus*
Deleting Menus *delete-menus*
*:unme* *:unmenu*
*:aun* *:aunmenu*
*:unme* *:unmenu*
*:aun* *:aunmenu*
To delete a menu item or a whole submenu, use the unmenu commands, which are
analogous to the unmap commands. Eg: >
:unmenu! Edit.Paste
@ -545,26 +548,26 @@ Command-line modes.
Note that hitting <Tab> while entering a menu name after an umenu command
may be used to complete the name of the menu item for the appropriate mode.
To remove all menus use: *:unmenu-all* >
:unmenu * " remove all menus in Normal and visual mode
:unmenu! * " remove all menus in Insert and Command-line mode
:aunmenu * " remove all menus in all modes, except for Terminal
" mode
:tlunmenu * " remove all menus in Terminal mode
To remove all menus use: *:unmenu-all* >
:unmenu * " remove all menus in Normal and visual mode
:unmenu! * " remove all menus in Insert and Command-line mode
:aunmenu * " remove all menus in all modes, except for Terminal
" mode
:tlunmenu * " remove all menus in Terminal mode
If you want to get rid of the menu bar: >
:set guioptions-=m
:set guioptions-=m
Disabling Menus *disable-menus*
Disabling Menus *disable-menus*
*:menu-disable* *:menu-enable*
*:menu-disable* *:menu-enable*
If you do not want to remove a menu, but disable it for a moment, this can be
done by adding the "enable" or "disable" keyword to a ":menu" command.
Examples: >
:menu disable &File.&Open\.\.\.
:amenu enable *
:amenu disable &Tools.*
:menu disable &File.&Open\.\.\.
:amenu enable *
:amenu disable &Tools.*
The command applies to the modes as used with all menu commands. Note that
characters like "&" need to be included for translated names to be found.
@ -572,36 +575,36 @@ When the argument is "*", all menus are affected. Otherwise the given menu
name and all existing submenus below it are affected.
Examples for Menus *menu-examples*
Examples for Menus *menu-examples*
Here is an example on how to add menu items with menus! You can add a menu
item for the keyword under the cursor. The register "z" is used. >
:nmenu Words.Add\ Var wb"zye:menu! Words.<C-R>z <C-R>z<CR>
:nmenu Words.Remove\ Var wb"zye:unmenu! Words.<C-R>z<CR>
:vmenu Words.Add\ Var "zy:menu! Words.<C-R>z <C-R>z <CR>
:vmenu Words.Remove\ Var "zy:unmenu! Words.<C-R>z<CR>
:imenu Words.Add\ Var <Esc>wb"zye:menu! Words.<C-R>z <C-R>z<CR>a
:imenu Words.Remove\ Var <Esc>wb"zye:unmenu! Words.<C-R>z<CR>a
:nmenu Words.Add\ Var wb"zye:menu! Words.<C-R>z <C-R>z<CR>
:nmenu Words.Remove\ Var wb"zye:unmenu! Words.<C-R>z<CR>
:vmenu Words.Add\ Var "zy:menu! Words.<C-R>z <C-R>z <CR>
:vmenu Words.Remove\ Var "zy:unmenu! Words.<C-R>z<CR>
:imenu Words.Add\ Var <Esc>wb"zye:menu! Words.<C-R>z <C-R>z<CR>a
:imenu Words.Remove\ Var <Esc>wb"zye:unmenu! Words.<C-R>z<CR>a
(the rhs is in <> notation, you can copy/paste this text to try out the
mappings, or put these lines in your gvimrc; "<C-R>" is CTRL-R, "<CR>" is
the <CR> key. |<>|)
*tooltips* *menu-tips*
*tooltips* *menu-tips*
Tooltips & Menu tips
See section |42.4| in the user manual.
*:tmenu*
:tm[enu] {menupath} {rhs} Define a tip for a menu or tool. (only in
X11 and Win32 GUI)
*:tmenu*
:tm[enu] {menupath} {rhs} Define a tip for a menu or tool. (only in
X11 and Win32 GUI)
:tm[enu] [menupath] List menu tips. (only in X11 and Win32 GUI)
:tm[enu] [menupath] List menu tips. (only in X11 and Win32 GUI)
*:tunmenu*
:tu[nmenu] {menupath} Remove a tip for a menu or tool.
(only in X11 and Win32 GUI)
*:tunmenu*
:tu[nmenu] {menupath} Remove a tip for a menu or tool.
(only in X11 and Win32 GUI)
Note: To create menus for terminal mode, use |:tlmenu| instead.
@ -615,11 +618,11 @@ highlight group to change its colors.
A "tip" can be defined for each menu item. For example, when defining a menu
item like this: >
:amenu MyMenu.Hello :echo "Hello"<CR>
:amenu MyMenu.Hello :echo "Hello"<CR>
The tip is defined like this: >
:tmenu MyMenu.Hello Displays a greeting.
:tmenu MyMenu.Hello Displays a greeting.
And delete it with: >
:tunmenu MyMenu.Hello
:tunmenu MyMenu.Hello
Tooltips are currently only supported for the X11 and Win32 GUI. However, they
should appear for the other gui platforms in the not too distant future.
@ -638,24 +641,24 @@ a menu item - you don't need to do a :tunmenu as well.
You can cause a menu to popup at the cursor. This behaves similarly to the
PopUp menus except that any menu tree can be popped up.
*:popup* *:popu*
:popu[p] {name} Popup the menu {name}. The menu named must
have at least one subentry, but need not
appear on the menu-bar (see |hidden-menus|).
*:popup* *:popu*
:popu[p] {name} Popup the menu {name}. The menu named must
have at least one subentry, but need not
appear on the menu-bar (see |hidden-menus|).
:popu[p]! {name} Like above, but use the position of the mouse
pointer instead of the cursor.
:popu[p]! {name} Like above, but use the position of the mouse
pointer instead of the cursor.
Example: >
:popup File
:popup File
will make the "File" menu (if there is one) appear at the text cursor (mouse
pointer if ! was used). >
:amenu ]Toolbar.Make :make<CR>
:popup ]Toolbar
:amenu ]Toolbar.Make :make<CR>
:popup ]Toolbar
This creates a popup menu that doesn't exist on the main menu-bar.
Note that a menu that starts with ']' will not be displayed.
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:
vim:tw=78:sw=4:ts=8:et:ft=help:norl:

View File

@ -150,6 +150,7 @@ LANGUAGE SUPPORT
|arabic.txt| Arabic language support and editing
|hebrew.txt| Hebrew language support and editing
|russian.txt| Russian language support and editing
|vietnamese.txt| Vietnamese language support and editing
------------------------------------------------------------------------------
INTEROP

View File

@ -1472,6 +1472,7 @@ tag command action ~
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|:packloadall| :packl[oadall] load all packages under 'packpath'
|:pbuffer| :pb[uffer] edit buffer in the preview window
|:pclose| :pc[lose] close preview window
|:pedit| :ped[it] edit file in the preview window
|:perl| :pe[rl] execute perl command
@ -1569,6 +1570,8 @@ tag command action ~
|:sign| :sig[n] manipulate signs
|:silent| :sil[ent] run a command silently
|:sleep| :sl[eep] do nothing for a few seconds
|:sleep!| :sl[eep]! do nothing for a few seconds, without the
cursor visible
|:slast| :sla[st] split window and go to last file in the
argument list
|:smagic| :sm[agic] :substitute with 'magic'

File diff suppressed because it is too large Load Diff

View File

@ -28,31 +28,114 @@ Follow these steps to get LSP features:
upstream installation instructions. You can find language servers here:
https://microsoft.github.io/language-server-protocol/implementors/servers/
2. Use |vim.lsp.start()| to start the LSP server (or attach to an existing
one) when a file is opened. Example: >lua
-- Create an event handler for the FileType autocommand
vim.api.nvim_create_autocmd('FileType', {
-- This handler will fire when the buffer's 'filetype' is "python"
pattern = 'python',
callback = function(args)
vim.lsp.start({
name = 'my-server-name',
cmd = {'name-of-language-server-executable', '--option', 'arg1', 'arg2'},
2. Use |vim.lsp.config()| to define a configuration for an LSP client.
Example: >lua
vim.lsp.config['luals'] = {
-- Command and arguments to start the server.
cmd = { 'lua-language-server' }
-- Set the "root directory" to the parent directory of the file in the
-- current buffer (`args.buf`) that contains either a "setup.py" or a
-- "pyproject.toml" file. Files that share a root directory will reuse
-- the connection to the same LSP server.
root_dir = vim.fs.root(args.buf, {'setup.py', 'pyproject.toml'}),
})
end,
})
-- Filetypes to automatically attach to.
filetypes = { 'lua' },
-- Sets the "root directory" to the parent directory of the file in the
-- current buffer that contains either a ".luarc.json" or a
-- ".luarc.jsonc" file. Files that share a root directory will reuse
-- the connection to the same LSP server.
root_markers = { '.luarc.json', '.luarc.jsonc' },
-- Specific settings to send to the server. The schema for this is
-- defined by the server. For example the schema for lua-language-server
-- can be found here https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json
settings = {
Lua = {
runtime = {
version = 'LuaJIT',
}
}
}
}
<
3. Check that the buffer is attached to the server: >vim
:checkhealth lsp
3. Use |vim.lsp.enable()| to enable a configuration.
Example: >lua
vim.lsp.enable('luals')
<
4. Check that the buffer is attached to the server: >vim
:checkhealth vim.lsp
<
5. (Optional) Configure keymaps and autocommands to use LSP features.
|lsp-attach|
4. (Optional) Configure keymaps and autocommands to use LSP features. |lsp-config|
*lsp-config*
Configurations for LSP clients is done via |vim.lsp.config()|.
When an LSP client starts, it resolves a configuration by merging
configurations, in increasing priority, from the following:
1. Configuration defined for the `'*'` name.
2. Configuration from the result of sourcing all `lsp/<name>.lua` files
in 'runtimepath' for a server of name `name`.
Note: because of this, calls to |vim.lsp.config()| in `lsp/*.lua` are
treated independently to other calls. This ensures configurations
defined in `lsp/*.lua` have a lower priority.
3. Configurations defined anywhere else.
Note: The merge semantics of configurations follow the behaviour of
|vim.tbl_deep_extend()|.
Example:
Given: >lua
-- Defined in init.lua
vim.lsp.config('*', {
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true,
}
}
}
root_markers = { '.git' },
})
-- Defined in ../lsp/clangd.lua
vim.lsp.config('clangd', {
cmd = { 'clangd' },
root_markers = { '.clangd', 'compile_commands.json' },
filetypes = { 'c', 'cpp' },
})
-- Defined in init.lua
vim.lsp.config('clangd', {
filetypes = { 'c' },
})
<
Results in the configuration: >lua
{
-- From the clangd configuration in <rtp>/lsp/clangd.lua
cmd = { 'clangd' },
-- From the clangd configuration in <rtp>/lsp/clangd.lua
-- Overrides the * configuration in init.lua
root_markers = { '.clangd', 'compile_commands.json' },
-- From the clangd configuration in init.lua
-- Overrides the * configuration in init.lua
filetypes = { 'c' },
-- From the * configuration in init.lua
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true,
}
}
}
}
<
*lsp-defaults*
When the Nvim LSP client starts it enables diagnostics |vim.diagnostic| (see
|vim.diagnostic.config()| to customize). It also sets various default options,
@ -98,7 +181,7 @@ To override or delete any of the above defaults, set or unset the options on
end,
})
<
*lsp-config*
*lsp-attach*
To use other LSP features, set keymaps and other buffer options on
|LspAttach|. Not all language servers provide the same capabilities. Use
capability checks to ensure you only use features supported by the language
@ -107,16 +190,16 @@ server. Example: >lua
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client.supports_method('textDocument/implementation') then
if client:supports_method('textDocument/implementation') then
-- Create a keymap for vim.lsp.buf.implementation
end
if client.supports_method('textDocument/completion') then
if client:supports_method('textDocument/completion') then
-- Enable auto-completion
vim.lsp.completion.enable(true, client.id, args.buf, {autotrigger = true})
end
if client.supports_method('textDocument/formatting') then
if client:supports_method('textDocument/formatting') then
-- Format the current buffer on save
vim.api.nvim_create_autocmd('BufWritePre', {
buffer = args.buf,
@ -204,6 +287,7 @@ won't run if your server doesn't support them.
- `'textDocument/diagnostic'`
- `'textDocument/documentHighlight'`
- `'textDocument/documentSymbol'`
- `'textDocument/foldingRange'`
- `'textDocument/formatting'`
- `'textDocument/hover'`
- `'textDocument/implementation'`
@ -464,7 +548,7 @@ EVENTS *lsp-events*
LspAttach *LspAttach*
After an LSP client attaches to a buffer. The |autocmd-pattern| is the
name of the buffer. When used from Lua, the client ID is passed to the
callback in the "data" table. See |lsp-config| for an example.
callback in the "data" table. See |lsp-attach| for an example.
LspDetach *LspDetach*
Just before an LSP client detaches from a buffer. The |autocmd-pattern|
@ -477,7 +561,7 @@ LspDetach *LspDetach*
local client = vim.lsp.get_client_by_id(args.data.client_id)
-- Remove the autocommand to format the buffer on save, if it exists
if client.supports_method('textDocument/formatting') then
if client:supports_method('textDocument/formatting') then
vim.api.nvim_clear_autocmds({
event = 'BufWritePre',
buffer = args.buf,
@ -589,6 +673,27 @@ LspTokenUpdate *LspTokenUpdate*
==============================================================================
Lua module: vim.lsp *lsp-core*
*vim.lsp.Config*
Extends: |vim.lsp.ClientConfig|
Fields: ~
• {cmd}? (`string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient`)
See `cmd` in |vim.lsp.ClientConfig|.
• {filetypes}? (`string[]`) Filetypes the client will attach to, if
activated by `vim.lsp.enable()`. If not provided,
then the client will attach to all filetypes.
• {root_markers}? (`string[]`) Directory markers (.e.g. '.git/') where
the LSP server will base its workspaceFolders,
rootUri, and rootPath on initialization. Unused if
`root_dir` is provided.
• {reuse_client}? (`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
Predicate used to decide if a client should be
re-used. Used on all running clients. The default
implementation re-uses a client if name and root_dir
matches.
buf_attach_client({bufnr}, {client_id}) *vim.lsp.buf_attach_client()*
Implements the `textDocument/did…` notifications required to track a
buffer for any language server.
@ -688,7 +793,7 @@ commands *vim.lsp.commands*
value is a function which is called if any LSP action (code action, code
lenses, ...) triggers the command.
If a LSP response contains a command for which no matching entry is
If an LSP response contains a command for which no matching entry is
available in this registry, the command will be executed via the LSP
server using `workspace/executeCommand`.
@ -697,6 +802,107 @@ commands *vim.lsp.commands*
The second argument is the `ctx` of |lsp-handler|
config({name}, {cfg}) *vim.lsp.config()*
Update the configuration for an LSP client.
Use name '*' to set default configuration for all clients.
Can also be table-assigned to redefine the configuration for a client.
Examples:
• Add a root marker for all clients: >lua
vim.lsp.config('*', {
root_markers = { '.git' },
})
<
• Add additional capabilities to all clients: >lua
vim.lsp.config('*', {
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true,
}
}
}
})
<
• (Re-)define the configuration for clangd: >lua
vim.lsp.config.clangd = {
cmd = {
'clangd',
'--clang-tidy',
'--background-index',
'--offset-encoding=utf-8',
},
root_markers = { '.clangd', 'compile_commands.json' },
filetypes = { 'c', 'cpp' },
}
<
• Get configuration for luals: >lua
local cfg = vim.lsp.config.luals
<
Parameters: ~
• {name} (`string`)
• {cfg} (`vim.lsp.Config`) See |vim.lsp.Config|.
enable({name}, {enable}) *vim.lsp.enable()*
Enable an LSP server to automatically start when opening a buffer.
Uses configuration defined with `vim.lsp.config`.
Examples: >lua
vim.lsp.enable('clangd')
vim.lsp.enable({'luals', 'pyright'})
<
Parameters: ~
• {name} (`string|string[]`) Name(s) of client(s) to enable.
• {enable} (`boolean?`) `true|nil` to enable, `false` to disable.
foldclose({kind}, {winid}) *vim.lsp.foldclose()*
Close all {kind} of folds in the the window with {winid}.
To automatically fold imports when opening a file, you can use an autocmd: >lua
vim.api.nvim_create_autocmd('LspNotify', {
callback = function(args)
if args.data.method == 'textDocument/didOpen' then
vim.lsp.foldclose('imports', vim.fn.bufwinid(args.buf))
end
end,
})
<
Parameters: ~
• {kind} (`lsp.FoldingRangeKind`) Kind to close, one of "comment",
"imports" or "region".
• {winid} (`integer?`) Defaults to the current window.
foldexpr({lnum}) *vim.lsp.foldexpr()*
Provides an interface between the built-in client and a `foldexpr`
function.
To use, check for the "textDocument/foldingRange" capability in an
|LspAttach| autocommand. Example: >lua
vim.api.nvim_create_autocommand('LspAttach', {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
if client:supports_method('textDocument/foldingRange') then
vim.wo.foldmethod = 'expr'
vim.wo.foldexpr = 'v:lua.vim.lsp.foldexpr()'
end
end,
})
<
Parameters: ~
• {lnum} (`integer`) line number
foldtext() *vim.lsp.foldtext()*
Provides a `foldtext` function that shows the `collapsedText` retrieved,
defaults to the first folded line if `collapsedText` is not provided.
formatexpr({opts}) *vim.lsp.formatexpr()*
Provides an interface between the built-in client and a `formatexpr`
function.
@ -798,12 +1004,11 @@ start({config}, {opts}) *vim.lsp.start()*
})
<
See |vim.lsp.start_client()| for all available options. The most important
See |vim.lsp.ClientConfig| for all available options. The most important
are:
• `name` arbitrary name for the LSP client. Should be unique per language
server.
• `cmd` command string[] or function, described at
|vim.lsp.start_client()|.
• `cmd` command string[] or function.
• `root_dir` path to the project root. By default this is used to decide
if an existing client should be re-used. The example above uses
|vim.fs.root()| to detect the root by traversing the file system upwards
@ -825,33 +1030,25 @@ start({config}, {opts}) *vim.lsp.start()*
Parameters: ~
• {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
|vim.lsp.ClientConfig|.
• {opts} (`table?`) Optional keyword arguments
• {opts} (`table?`) Optional keyword arguments.
• {reuse_client}?
(`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
Predicate used to decide if a client should be re-used.
Used on all running clients. The default implementation
re-uses a client if name and root_dir matches.
re-uses a client if it has the same name and if the given
workspace folders (or root_dir) are all included in the
client's workspace folders.
• {bufnr}? (`integer`) Buffer handle to attach to if
starting or re-using a client (0 for current).
• {attach}? (`boolean`) Whether to attach the client to a
buffer (default true). If set to `false`, `reuse_client`
and `bufnr` will be ignored.
• {silent}? (`boolean`) Suppress error reporting if the LSP
server fails to start (default false).
Return: ~
(`integer?`) client_id
start_client({config}) *vim.lsp.start_client()*
Starts and initializes a client with the given configuration.
Parameters: ~
• {config} (`vim.lsp.ClientConfig`) Configuration for the server. See
|vim.lsp.ClientConfig|.
Return (multiple): ~
(`integer?`) client_id |vim.lsp.get_client_by_id()| Note: client may
not be fully initialized. Use `on_init` to do any actions once the
client has been initialized.
(`string?`) Error message, if any
status() *vim.lsp.status()*
Consumes the latest progress messages from all clients and formats them as
a string. Empty if there are no clients or if no new messages
@ -904,14 +1101,15 @@ Lua module: vim.lsp.client *lsp-client*
• {rpc} (`vim.lsp.rpc.PublicClient`) RPC client
object, for low level interaction with the
client. See |vim.lsp.rpc.start()|.
• {offset_encoding} (`string`) The encoding used for communicating
with the server. You can modify this in the
• {offset_encoding} (`string`) Called "position encoding" in LSP
spec, the encoding used for communicating with
the server. You can modify this in the
`config`'s `on_init` method before text is
sent to the server.
• {handlers} (`table<string,lsp.Handler>`) The handlers
used by the client as described in
|lsp-handler|.
• {requests} (`table<integer,{ type: string, bufnr: integer, method: string}>`)
• {requests} (`table<integer,{ type: string, bufnr: integer, method: string}?>`)
The current pending requests in flight to the
server. Entries are key-value pairs with the
key being the request id while the value is a
@ -924,8 +1122,7 @@ Lua module: vim.lsp.client *lsp-client*
server.
• {config} (`vim.lsp.ClientConfig`) copy of the table
that was passed by the user to
|vim.lsp.start_client()|. See
|vim.lsp.ClientConfig|.
|vim.lsp.start()|. See |vim.lsp.ClientConfig|.
• {server_capabilities} (`lsp.ServerCapabilities?`) Response from the
server sent on `initialize` describing the
server's capabilities.
@ -948,9 +1145,9 @@ Lua module: vim.lsp.client *lsp-client*
lenses, ...) triggers the command. Client
commands take precedence over the global
command registry.
• {settings} (`table`) Map with language server specific
settings. These are returned to the language
server if requested via
• {settings} (`lsp.LSPObject`) Map with language server
specific settings. These are returned to the
language server if requested via
`workspace/configuration`. Keys are
case-sensitive.
• {flags} (`table`) A table with flags for the client.
@ -974,7 +1171,7 @@ Lua module: vim.lsp.client *lsp-client*
• {dynamic_capabilities} (`lsp.DynamicCapabilities`)
• {request} (`fun(self: vim.lsp.Client, method: string, params: table?, handler: lsp.Handler?, bufnr: integer?): boolean, integer?`)
See |Client:request()|.
• {request_sync} (`fun(self: vim.lsp.Client, method: string, params: table, timeout_ms: integer?, bufnr: integer): {err: lsp.ResponseError?, result:any}?, string?`)
• {request_sync} (`fun(self: vim.lsp.Client, method: string, params: table, timeout_ms: integer?, bufnr: integer?): {err: lsp.ResponseError?, result:any}?, string?`)
See |Client:request_sync()|.
• {notify} (`fun(self: vim.lsp.Client, method: string, params: table?): boolean`)
See |Client:notify()|.
@ -1043,28 +1240,30 @@ Lua module: vim.lsp.client *lsp-client*
an array.
• {handlers}? (`table<string,function>`) Map of language
server method names to |lsp-handler|
• {settings}? (`table`) Map with language server specific
settings. See the {settings} in
• {settings}? (`lsp.LSPObject`) Map with language server
specific settings. See the {settings} in
|vim.lsp.Client|.
• {commands}? (`table<string,fun(command: lsp.Command, ctx: table)>`)
Table that maps string of clientside commands to
user-defined functions. Commands passed to
start_client take precedence over the global
`start()` take precedence over the global
command registry. Each key must be a unique
command name, and the value is a function which
is called if any LSP action (code action, code
lenses, ...) triggers the command.
• {init_options}? (`table`) Values to pass in the initialization
request as `initializationOptions`. See
`initialize` in the LSP spec.
• {init_options}? (`lsp.LSPObject`) Values to pass in the
initialization request as
`initializationOptions`. See `initialize` in the
LSP spec.
• {name}? (`string`, default: client-id) Name in log
messages.
• {get_language_id}? (`fun(bufnr: integer, filetype: string): string`)
Language ID as string. Defaults to the buffer
filetype.
• {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) The encoding that
the LSP server expects. Client does not verify
this is correct.
• {offset_encoding}? (`'utf-8'|'utf-16'|'utf-32'`) Called "position
encoding" in LSP spec, the encoding that the LSP
server expects. Client does not verify this is
correct.
• {on_error}? (`fun(code: integer, err: string)`) Callback
invoked when the client operation throws an
error. `code` is a number describing the error.
@ -1077,9 +1276,9 @@ Lua module: vim.lsp.client *lsp-client*
Callback invoked before the LSP "initialize"
phase, where `params` contains the parameters
being sent to the server and `config` is the
config that was passed to
|vim.lsp.start_client()|. You can use this to
modify parameters before they are sent.
config that was passed to |vim.lsp.start()|. You
can use this to modify parameters before they
are sent.
• {on_init}? (`elem_or_list<fun(client: vim.lsp.Client, initialize_result: lsp.InitializeResult)>`)
Callback invoked after LSP "initialize", where
`result` is a table of `capabilities` and
@ -1177,7 +1376,7 @@ Client:request({method}, {params}, {handler}, {bufnr})
• {method} (`string`) LSP method name.
• {params} (`table?`) LSP request params.
• {handler} (`lsp.Handler?`) Response |lsp-handler| for this method.
• {bufnr} (`integer?`) Buffer handle. 0 for current (default).
• {bufnr} (`integer?`) (default: 0) Buffer handle, or 0 for current.
Return (multiple): ~
(`boolean`) status indicates whether the request was successful. If it
@ -1199,7 +1398,8 @@ Client:request_sync({method}, {params}, {timeout_ms}, {bufnr})
• {params} (`table`) LSP request params.
• {timeout_ms} (`integer?`) Maximum time in milliseconds to wait for a
result. Defaults to 1000
• {bufnr} (`integer`) Buffer handle (0 for current).
• {bufnr} (`integer?`) (default: 0) Buffer handle, or 0 for
current.
Return (multiple): ~
(`{err: lsp.ResponseError?, result:any}?`) `result` and `err` from the
@ -1383,7 +1583,7 @@ format({opts}) *vim.lsp.buf.format()*
predicate are included. Example: >lua
-- Never request typescript-language-server for formatting
vim.lsp.buf.format {
filter = function(client) return client.name ~= "tsserver" end
filter = function(client) return client.name ~= "ts_ls" end
}
<
• {async}? (`boolean`, default: false) If true the method
@ -1446,7 +1646,7 @@ references({context}, {opts}) *vim.lsp.buf.references()*
window.
Parameters: ~
• {context} (`table?`) Context for the request
• {context} (`lsp.ReferenceContext?`) Context for the request
• {opts} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
See also: ~
@ -1532,12 +1732,13 @@ get_namespace({client_id}, {is_pull})
client. Defaults to push
*vim.lsp.diagnostic.on_diagnostic()*
on_diagnostic({_}, {result}, {ctx})
on_diagnostic({error}, {result}, {ctx})
|lsp-handler| for the method "textDocument/diagnostic"
See |vim.diagnostic.config()| for configuration options.
Parameters: ~
• {error} (`lsp.ResponseError?`)
• {result} (`lsp.DocumentDiagnosticReport`)
• {ctx} (`lsp.HandlerContext`)
@ -1840,7 +2041,7 @@ Lua module: vim.lsp.util *lsp-util*
*vim.lsp.util.apply_text_document_edit()*
apply_text_document_edit({text_document_edit}, {index}, {offset_encoding})
apply_text_document_edit({text_document_edit}, {index}, {position_encoding})
Applies a `TextDocumentEdit`, which is a list of changes to a single
document.
@ -1848,30 +2049,30 @@ apply_text_document_edit({text_document_edit}, {index}, {offset_encoding})
• {text_document_edit} (`lsp.TextDocumentEdit`)
• {index} (`integer?`) Optional index of the edit, if from
a list of edits (or nil, if not from a list)
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit
*vim.lsp.util.apply_text_edits()*
apply_text_edits({text_edits}, {bufnr}, {offset_encoding})
apply_text_edits({text_edits}, {bufnr}, {position_encoding})
Applies a list of text edits to a buffer.
Parameters: ~
• {text_edits} (`lsp.TextEdit[]`)
• {bufnr} (`integer`) Buffer id
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
• {text_edits} (`lsp.TextEdit[]`)
• {bufnr} (`integer`) Buffer id
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
*vim.lsp.util.apply_workspace_edit()*
apply_workspace_edit({workspace_edit}, {offset_encoding})
apply_workspace_edit({workspace_edit}, {position_encoding})
Applies a `WorkspaceEdit`.
Parameters: ~
• {workspace_edit} (`lsp.WorkspaceEdit`)
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`) (required)
• {workspace_edit} (`lsp.WorkspaceEdit`)
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`) (required)
See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
@ -1883,13 +2084,13 @@ buf_clear_references({bufnr}) *vim.lsp.util.buf_clear_references()*
• {bufnr} (`integer?`) Buffer id
*vim.lsp.util.buf_highlight_references()*
buf_highlight_references({bufnr}, {references}, {offset_encoding})
buf_highlight_references({bufnr}, {references}, {position_encoding})
Shows a list of document highlights for a certain buffer.
Parameters: ~
• {bufnr} (`integer`) Buffer id
• {references} (`lsp.DocumentHighlight[]`) objects to highlight
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
• {bufnr} (`integer`) Buffer id
• {references} (`lsp.DocumentHighlight[]`) objects to highlight
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
See also: ~
• https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
@ -1964,7 +2165,7 @@ get_effective_tabstop({bufnr}) *vim.lsp.util.get_effective_tabstop()*
• 'shiftwidth'
*vim.lsp.util.locations_to_items()*
locations_to_items({locations}, {offset_encoding})
locations_to_items({locations}, {position_encoding})
Returns the items with the byte position calculated correctly and in
sorted order, for display in quickfix and location lists.
@ -1975,9 +2176,9 @@ locations_to_items({locations}, {offset_encoding})
|setloclist()|.
Parameters: ~
• {locations} (`lsp.Location[]|lsp.LocationLink[]`)
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first
client of buffer
• {locations} (`lsp.Location[]|lsp.LocationLink[]`)
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`) default to first
client of buffer
Return: ~
(`vim.quickfix.entry[]`) See |setqflist()| for the format
@ -2012,33 +2213,33 @@ make_formatting_params({options})
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_formatting
*vim.lsp.util.make_given_range_params()*
make_given_range_params({start_pos}, {end_pos}, {bufnr}, {offset_encoding})
make_given_range_params({start_pos}, {end_pos}, {bufnr}, {position_encoding})
Using the given range in the current buffer, creates an object that is
similar to |vim.lsp.util.make_range_params()|.
Parameters: ~
• {start_pos} (`[integer,integer]?`) {row,col} mark-indexed
position. Defaults to the start of the last visual
selection.
• {end_pos} (`[integer,integer]?`) {row,col} mark-indexed
position. Defaults to the end of the last visual
selection.
• {bufnr} (`integer?`) buffer handle or 0 for current,
defaults to current
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
• {start_pos} (`[integer,integer]?`) {row,col} mark-indexed
position. Defaults to the start of the last
visual selection.
• {end_pos} (`[integer,integer]?`) {row,col} mark-indexed
position. Defaults to the end of the last visual
selection.
• {bufnr} (`integer?`) buffer handle or 0 for current,
defaults to current
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
Return: ~
(`{ textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }`)
*vim.lsp.util.make_position_params()*
make_position_params({window}, {offset_encoding})
make_position_params({window}, {position_encoding})
Creates a `TextDocumentPositionParams` object for the current buffer and
cursor position.
Parameters: ~
• {window} (`integer?`) window handle or 0 for current,
defaults to current
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
• {window} (`integer?`) window handle or 0 for current,
defaults to current
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'`)
Return: ~
(`lsp.TextDocumentPositionParams`)
@ -2047,16 +2248,16 @@ make_position_params({window}, {offset_encoding})
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
*vim.lsp.util.make_range_params()*
make_range_params({window}, {offset_encoding})
make_range_params({window}, {position_encoding})
Using the current position in the current buffer, creates an object that
can be used as a building block for several LSP requests, such as
`textDocument/codeAction`, `textDocument/colorPresentation`,
`textDocument/rangeFormatting`.
Parameters: ~
• {window} (`integer?`) window handle or 0 for current,
defaults to current
• {offset_encoding} (`"utf-8"|"utf-16"|"utf-32"`)
• {window} (`integer?`) window handle or 0 for current,
defaults to current
• {position_encoding} (`"utf-8"|"utf-16"|"utf-32"`)
Return: ~
(`{ textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }`)
@ -2138,17 +2339,17 @@ rename({old_fname}, {new_fname}, {opts}) *vim.lsp.util.rename()*
• {ignoreIfExists}? (`boolean`)
*vim.lsp.util.show_document()*
show_document({location}, {offset_encoding}, {opts})
show_document({location}, {position_encoding}, {opts})
Shows document and optionally jumps to the location.
Parameters: ~
• {location} (`lsp.Location|lsp.LocationLink`)
• {offset_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
• {opts} (`table?`) A table with the following fields:
• {reuse_win}? (`boolean`) Jump to existing window
if buffer is already open.
• {focus}? (`boolean`) Whether to focus/jump to
location if possible. (defaults: true)
• {location} (`lsp.Location|lsp.LocationLink`)
• {position_encoding} (`'utf-8'|'utf-16'|'utf-32'?`)
• {opts} (`table?`) A table with the following fields:
• {reuse_win}? (`boolean`) Jump to existing
window if buffer is already open.
• {focus}? (`boolean`) Whether to focus/jump to
location if possible. (defaults: true)
Return: ~
(`boolean`) `true` if succeeded
@ -2232,14 +2433,15 @@ should_log({level}) *vim.lsp.log.should_log()*
Lua module: vim.lsp.rpc *lsp-rpc*
*vim.lsp.rpc.PublicClient*
Client RPC object
Fields: ~
• {request} (`fun(method: string, params: table?, callback: fun(err: lsp.ResponseError?, result: any), notify_reply_callback: fun(message_id: integer)?):boolean,integer?`)
see |vim.lsp.rpc.request()|
• {notify} (`fun(method: string, params: any):boolean`) see
• {request} (`fun(method: string, params: table?, callback: fun(err?: lsp.ResponseError, result: any), notify_reply_callback?: fun(message_id: integer)):boolean,integer?`)
See |vim.lsp.rpc.request()|
• {notify} (`fun(method: string, params: any): boolean`) See
|vim.lsp.rpc.notify()|
• {is_closing} (`fun(): boolean`)
• {terminate} (`fun()`)
• {is_closing} (`fun(): boolean`) Indicates if the RPC is closing.
• {terminate} (`fun()`) Terminates the RPC client.
connect({host_or_path}, {port}) *vim.lsp.rpc.connect()*
@ -2249,7 +2451,7 @@ connect({host_or_path}, {port}) *vim.lsp.rpc.connect()*
• a host and port via TCP
Return a function that can be passed to the `cmd` field for
|vim.lsp.start_client()| or |vim.lsp.start()|.
|vim.lsp.start()|.
Parameters: ~
• {host_or_path} (`string`) host to connect to or path to a pipe/domain
@ -2340,12 +2542,7 @@ start({cmd}, {dispatchers}, {extra_spawn_params}) *vim.lsp.rpc.start()*
See |vim.system()|
Return: ~
(`vim.lsp.rpc.PublicClient`) Client RPC object, with these methods:
• `notify()` |vim.lsp.rpc.notify()|
• `request()` |vim.lsp.rpc.request()|
• `is_closing()` returns a boolean indicating if the RPC is closing.
• `terminate()` terminates the RPC client. See
|vim.lsp.rpc.PublicClient|.
(`vim.lsp.rpc.PublicClient`) See |vim.lsp.rpc.PublicClient|.
==============================================================================

View File

@ -17,9 +17,9 @@ get an idea of what lurks beneath: >vim
:lua vim.print(package.loaded)
Nvim includes a "standard library" |lua-stdlib| for Lua. It complements the
"editor stdlib" (|builtin-functions| and |Ex-commands|) and the |API|, all of
which can be used from Lua code (|lua-vimscript| |vim.api|). Together these
"namespaces" form the Nvim programming interface.
"editor stdlib" (|vimscript-functions| + |Ex-commands|) and the |API|, all of
which can be used from Lua code (|lua-vimscript| |vim.api|). These three
namespaces form the Nvim programming interface.
Lua plugins and user config are automatically discovered and loaded, just like
Vimscript. See |lua-guide| for practical guidance.
@ -811,11 +811,14 @@ vim.json.decode({str}, {opts}) *vim.json.decode()*
Return: ~
(`any`)
vim.json.encode({obj}) *vim.json.encode()*
vim.json.encode({obj}, {opts}) *vim.json.encode()*
Encodes (or "packs") Lua object {obj} as JSON in a Lua string.
Parameters: ~
• {obj} (`any`)
• {obj} (`any`)
• {opts} (`table<string,any>?`) Options table with keys:
• escape_slash: (boolean) (default false) When true, escapes
`/` character in JSON strings
Return: ~
(`string`)
@ -1911,6 +1914,11 @@ vim.show_pos({bufnr}, {row}, {col}, {filter}) *vim.show_pos()*
Can also be shown with `:Inspect`. *:Inspect*
Example: To bind this function to the vim-scriptease inspired `zS` in
Normal mode: >lua
vim.keymap.set('n', 'zS', vim.show_pos)
<
Attributes: ~
Since: 0.9.0
@ -2469,7 +2477,7 @@ vim.validate({name}, {value}, {validator}, {optional}, {message})
Parameters: ~
• {name} (`string`) Argument name
• {value} (`string`) Argument value
• {value} (`any`) Argument value
• {validator} (`vim.validate.Validator`)
• (`string|string[]`): Any value that can be returned
from |lua-type()| in addition to `'callable'`:
@ -2485,22 +2493,24 @@ vim.validate({name}, {value}, {validator}, {optional}, {message})
==============================================================================
Lua module: vim.loader *vim.loader*
vim.loader.disable() *vim.loader.disable()*
vim.loader.enable({enable}) *vim.loader.enable()*
WARNING: This feature is experimental/unstable.
Disables the experimental Lua module loader:
• removes the loaders
• adds the default Nvim loader
Enables or disables the experimental Lua module loader:
vim.loader.enable() *vim.loader.enable()*
WARNING: This feature is experimental/unstable.
Enables the experimental Lua module loader:
• overrides loadfile
Enable (`enable=true`):
• overrides |loadfile()|
• adds the Lua loader using the byte-compilation cache
• adds the libs loader
• removes the default Nvim loader
Disable (`enable=false`):
• removes the loaders
• adds the default Nvim loader
Parameters: ~
• {enable} (`boolean?`) true/nil to enable, false to disable
vim.loader.find({modname}, {opts}) *vim.loader.find()*
WARNING: This feature is experimental/unstable.
@ -2924,6 +2934,17 @@ vim.keymap.set({mode}, {lhs}, {rhs}, {opts}) *vim.keymap.set()*
==============================================================================
Lua module: vim.fs *vim.fs*
*vim.fs.exists()*
Use |uv.fs_stat()| to check a file's type, and whether it exists.
Example: >lua
if vim.uv.fs_stat(file) then
vim.print("file exists")
end
<
vim.fs.basename({file}) *vim.fs.basename()*
Return the basename of the given path

View File

@ -12,7 +12,7 @@ manual.
Type |gO| to see the table of contents.
==============================================================================
1. Key mapping *key-mapping* *mapping* *macro*
1. Key mapping *keybind* *key-mapping* *mapping* *macro*
Key mapping is used to change the meaning of typed keys. The most common use
is to define a sequence of commands for a function key. Example: >

View File

@ -27,7 +27,7 @@ depends on the 'shortmess' option.
Clear messages, keeping only the {count} most
recent ones.
The number of remembered messages is fixed at 200.
The number of remembered messages is determined by the 'messagesopt' option.
*g<*
The "g<" command can be used to see the last page of previous command output.
@ -789,6 +789,7 @@ If you accidentally hit <Enter> or <Space> and you want to see the displayed
text then use |g<|. This only works when 'more' is set.
To reduce the number of hit-enter prompts:
- Set 'messagesopt'.
- Set 'cmdheight' to 2 or higher.
- Add flags to 'shortmess'.
- Reset 'showcmd' and/or 'ruler'.

View File

@ -115,6 +115,12 @@ This cannot be repeated: >
endif<CR>
Note that when using ":" any motion becomes charwise exclusive.
*inclusive-motion-selection-exclusive*
When 'selection' is "exclusive", |Visual| mode is active and an inclusive
motion has been used, the cursor position will be adjusted by another
character to the right, so that the Visual selection includes the expected
text and can be acted upon.
*forced-motion*
FORCING A MOTION TO BE LINEWISE, CHARWISE OR BLOCKWISE

View File

@ -11,16 +11,21 @@ For changes in the previous release, see |news-0.10|.
Type |gO| to see the table of contents.
==============================================================================
BREAKING CHANGES IN HEAD *news-breaking-dev*
BREAKING CHANGES IN HEAD OR EXPERIMENTAL *news-breaking-dev*
====== Remove this section before release. ======
The following changes to UNRELEASED features were made during the development
cycle (Nvim HEAD, the "master" branch).
EXPERIMENTS
• Removed `vim.loader.disable()`. Use `vim.loader.enable(false)` instead.
OPTIONS
• 'jumpoptions' flag "unload" has been renamed to "clean".
• The `msghistory` option has been removed in favor of 'messagesopt'.
==============================================================================
BREAKING CHANGES *news-breaking*
@ -54,6 +59,9 @@ DEFAULTS
• |]d-default| and |[d-default| accept a count.
• |[D-default| and |]D-default| jump to the first and last diagnostic in the
current buffer, respectively.
• 'number', 'relativenumber', 'signcolumn', and 'foldcolumn' are disabled in
|terminal| buffers. See |terminal-config| for an example of changing these defaults.
• |vim.json.encode()| no longer escapes the forward slash symbol by default
DIAGNOSTICS
@ -79,6 +87,11 @@ EVENTS
• |vim.ui_attach()| callbacks for |ui-messages| `msg_show` events are executed in
|api-fast| context.
HIGHLIGHTS
• |TermCursorNC| is removed and no longer supported. Unfocused terminals no
longer have a cursor.
LSP
• Improved rendering of LSP hover docs. |K-lsp-default|
@ -100,7 +113,7 @@ LSP
vim.diagnostic.config(config, vim.lsp.diagnostic.get_namespace(client_id))
<
• |vim.lsp.util.make_position_params()|, |vim.lsp.util.make_range_params()|
and |vim.lsp.util.make_given_range_params()| now require the `offset_encoding`
and |vim.lsp.util.make_given_range_params()| now require the `position_encoding`
parameter.
LUA
@ -163,6 +176,7 @@ The following new features were added.
API
• |nvim__ns_set()| can set properties for a namespace
• |vim.json.encode()| has an option to enable forward slash escaping
DEFAULTS
@ -202,6 +216,7 @@ EDITOR
• On Windows, filename arguments on the command-line prefixed with "~\" or
"~/" are now expanded to the user's profile directory, not a relative path
to a literal "~" directory.
• |hl-ComplMatchIns| shows matched text of the currently inserted completion.
• |hl-PmenuMatch| and |hl-PmenuMatchSel| show matched text in completion popup.
EVENTS
@ -226,6 +241,11 @@ LSP
• |vim.lsp.buf.hover()| now highlights hover ranges using the
|hl-LspReferenceTarget| highlight group.
• Functions in |vim.lsp.Client| can now be called as methods.
• Implemented LSP folding: |vim.lsp.foldexpr()|
https://microsoft.github.io/language-server-protocol/specification/#textDocument_foldingRange
• |vim.lsp.config()| has been added to define default configurations for
servers. In addition, configurations can be specified in `lsp/<name>.lua`.
• |vim.lsp.enable()| has been added to enable servers.
LUA
@ -238,12 +258,13 @@ LUA
OPTIONS
• 'completeopt' flag "fuzzy" enables |fuzzy-matching| during |ins-completion|.
• 'msghistory' controls maximum number of messages to remember.
• 'messagesopt' configures |:messages| and |hit-enter| prompt.
• 'tabclose' controls which tab page to focus when closing a tab page.
PERFORMANCE
• TODO
• Significantly reduced redraw time for long lines with treesitter
highlighting.
PLUGINS
@ -266,12 +287,22 @@ TERMINAL
'scrollback' are not reflown.
• The |terminal| now supports OSC 8 escape sequences and will display
hyperlinks in supporting host terminals.
• The |terminal| now uses the actual cursor, rather than a "virtual" cursor.
This means that escape codes sent by applications running in a terminal
buffer can change the cursor shape and visibility. However, it also
means that the |TermCursorNC| highlight group is no longer supported: an
unfocused terminal window will have no cursor at all (so there is nothing to
highlight).
• |jobstart()| gained the "term" flag.
TREESITTER
• |LanguageTree:node_for_range()| gets anonymous and named nodes for a range
• |vim.treesitter.get_node()| now takes an option `include_anonymous`, default
false, which allows it to return anonymous nodes as well as named nodes.
• |treesitter-directive-trim!| can trim all whitespace (not just empty lines)
from both sides of a node.
• |vim.treesitter.get_captures_at_pos()| now returns the `id` of each capture
TUI
@ -280,6 +311,8 @@ TUI
:lua =vim.api.nvim_get_chan_info(vim.api.nvim_list_uis()[1].chan)
• |log| messages written by the builtin UI client (TUI, |--remote-ui|) are
now prefixed with "ui" instead of "?".
• The TUI will re-query the terminal's background color when a theme update
notification is received and Nvim will update 'background' accordingly.
UI
@ -287,7 +320,7 @@ UI
which controls the tool used to open the given path or URL. If you want to
globally set this, you can override vim.ui.open using the same approach
described at |vim.paste()|.
- `vim.ui.open()` now supports
`vim.ui.open()` now supports
[lemonade](https://github.com/lemonade-command/lemonade) as an option for
opening urls/files. This is handy if you are in an ssh connection and use
`lemonade`.
@ -295,7 +328,8 @@ UI
|hl-PmenuSel| and |hl-PmenuMatch| both inherit from |hl-Pmenu|, and
|hl-PmenuMatchSel| inherits highlights from both |hl-PmenuSel| and
|hl-PmenuMatch|.
• |vim.diagnostic.setqflist()| updates an existing quickfix list with the
given title if found
• |ui-messages| content chunks now also contain the highlight group ID.
==============================================================================
@ -317,9 +351,9 @@ These existing features changed their behavior.
more emoji characters than before, including those encoded with multiple
emoji codepoints combined with ZWJ (zero width joiner) codepoints.
Text in the 'statusline', 'tabline', and 'winbar' now inherits highlights
from the respective |hl-StatusLine|, |hl-TabLine|, and |hl-WinBar| highlight
groups.
Custom highlights in 'rulerformat', 'statuscolumn', 'statusline', 'tabline',
'winbar' and the number column (through |:sign-define| `numhl`) now combine
with their respective highlight groups, as opposed to |hl-Normal|.
• |vim.on_key()| callbacks won't be invoked recursively when a callback itself
consumes input.

View File

@ -6,21 +6,23 @@
Nvim *nvim* *neovim* *nvim-intro*
Nvim is based on Vim by Bram Moolenaar.
Nvim is based on Vim by Bram Moolenaar. Nvim is emphatically a fork of Vim,
not a clone: compatibility with Vim (especially editor and Vimscript features,
except |Vim9script|) is maintained where possible. See |vim-differences| for
the complete reference.
If you already use Vim see |nvim-from-vim| for a quickstart.
If you are new to Vim, try the 30-minute tutorial: >vim
If you already use Vim, see |nvim-from-vim| for a quickstart. If you just
installed Nvim and have never used it before, watch this 10-minute
video: https://youtu.be/TQn2hJeHQbM .
To learn how to use Vim in 30 minutes, try the tutorial: >vim
:Tutor<Enter>
Nvim is emphatically a fork of Vim, not a clone: compatibility with Vim
(especially editor and Vimscript features) is maintained where possible. See
|vim-differences| for the complete reference of differences from Vim.
<
Type |gO| to see the table of contents.
==============================================================================
Transitioning from Vim *nvim-from-vim*
Transitioning from Vim *nvim-from-vim*
1. To start the transition, create your |init.vim| (user config) file: >vim
@ -70,5 +72,21 @@ the same Nvim configuration on all of your machines, by creating
~/AppData/Local/nvim/init.vim containing just this line: >vim
source ~/.config/nvim/init.vim
==============================================================================
What next? *nvim-quickstart*
If you are just trying out Nvim for a few minutes, and want to see the
extremes of what it can do, try one of these popular "extension packs" or
"distributions" (Note: Nvim is not affiliated with these projects, and does
not support them):
- *kickstart* https://github.com/nvim-lua/kickstart.nvim
- *lazyvim* https://www.lazyvim.org/
- *nvchad* https://nvchad.com/
However, in general, we recommend (eventually) taking time to learn Nvim from
its stock configuration, and incrementally setting options and adding plugins
to your |config| as you find an explicit need to do so.
==============================================================================
vim:tw=78:ts=8:et:ft=help:norl:

View File

@ -1559,9 +1559,9 @@ A jump table for the options with a short description can be found at |Q_op|.
a match from the menu. Only works in combination with
"menu" or "menuone". No effect if "longest" is present.
noselect Do not select a match in the menu, force the user to
select one from the menu. Only works in combination with
"menu" or "menuone".
noselect Same as "noinsert", except that no menu item is
pre-selected. If both "noinsert" and "noselect" are present,
"noselect" has precedence.
fuzzy Enable |fuzzy-matching| for completion candidates. This
allows for more flexible and intuitive matching, where
@ -2977,7 +2977,7 @@ A jump table for the options with a short description can be found at |Q_op|.
An |OptionSet| autocmd can be used to set it up to match automatically.
*'guicursor'* *'gcr'* *E545* *E546* *E548* *E549*
'guicursor' 'gcr' string (default "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20")
'guicursor' 'gcr' string (default "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor")
global
Configures the cursor style for each mode. Works in the GUI and many
terminals. See |tui-cursor-shape|.
@ -3005,6 +3005,7 @@ A jump table for the options with a short description can be found at |Q_op|.
ci Command-line Insert mode
cr Command-line Replace mode
sm showmatch in Insert mode
t Terminal mode
a all modes
The argument-list is a dash separated list of these arguments:
hor{N} horizontal bar, {N} percent of the character height
@ -3021,7 +3022,8 @@ A jump table for the options with a short description can be found at |Q_op|.
cursor is not shown. Times are in msec. When one of
the numbers is zero, there is no blinking. E.g.: >vim
set guicursor=n:blinkon0
< - Default is "blinkon0" for each mode.
<
Default is "blinkon0" for each mode.
{group-name}
Highlight group that decides the color and font of the
cursor.
@ -3197,7 +3199,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global
A history of ":" commands, and a history of previous search patterns
is remembered. This option decides how many entries may be stored in
each of these histories (see |cmdline-editing| and 'msghistory' for
each of these histories (see |cmdline-editing| and 'messagesopt' for
the number of messages to remember).
The maximum value is 10000.
@ -4045,6 +4047,28 @@ A jump table for the options with a short description can be found at |Q_op|.
generated from a list of items, e.g., the Buffers menu. Changing this
option has no direct effect, the menu must be refreshed first.
*'messagesopt'* *'mopt'*
'messagesopt' 'mopt' string (default "hit-enter,history:500")
global
Option settings for outputting messages. It can consist of the
following items. Items must be separated by a comma.
hit-enter Use a |hit-enter| prompt when the message is longer than
'cmdheight' size.
wait:{n} Instead of using a |hit-enter| prompt, simply wait for
{n} milliseconds so that the user has a chance to read
the message. The maximum value of {n} is 10000. Use
0 to disable the wait (but then the user may miss an
important message).
This item is ignored when "hit-enter" is present, but
required when "hit-enter" is not present.
history:{n} Determines how many entries are remembered in the
|:messages| history. The maximum value is 10000.
Setting it to zero clears the message history.
This item must always be present.
*'mkspellmem'* *'msm'*
'mkspellmem' 'msm' string (default "460000,2000,500")
global
@ -4290,13 +4314,6 @@ A jump table for the options with a short description can be found at |Q_op|.
Defines the maximum time in msec between two mouse clicks for the
second click to be recognized as a multi click.
*'msghistory'* *'mhi'*
'msghistory' 'mhi' number (default 500)
global
Determines how many entries are remembered in the |:messages| history.
The maximum value is 10000.
Setting it to zero clears the message history.
*'nrformats'* *'nf'*
'nrformats' 'nf' string (default "bin,hex")
local to buffer
@ -4795,6 +4812,7 @@ A jump table for the options with a short description can be found at |Q_op|.
indent/ indent scripts |indent-expression|
keymap/ key mapping files |mbyte-keymap|
lang/ menu translations |:menutrans|
lsp/ LSP client configurations |lsp-config|
lua/ |Lua| plugins
menu.vim GUI menus |menu.vim|
pack/ packages |:packadd|
@ -4966,6 +4984,8 @@ A jump table for the options with a short description can be found at |Q_op|.
selection.
When "old" is used and 'virtualedit' allows the cursor to move past
the end of line the line break still isn't included.
When "exclusive" is used, cursor position in visual mode will be
adjusted for inclusive motions |inclusive-motion-selection-exclusive|.
Note that when "exclusive" is used and selecting from the end
backwards, you cannot include the last character of a line, when
starting in Normal mode and 'virtualedit' empty.
@ -5917,6 +5937,7 @@ A jump table for the options with a short description can be found at |Q_op|.
All fields except the {item} are optional. A single percent sign can
be given as "%%".
*stl-%!*
When the option starts with "%!" then it is used as an expression,
evaluated and the result is used as the option value. Example: >vim
set statusline=%!MyStatusLine()

View File

@ -193,7 +193,7 @@ registers. Nvim looks for these clipboard tools, in order of priority:
- xclip (if $DISPLAY is set)
- lemonade (for SSH) https://github.com/pocke/lemonade
- doitclient (for SSH) https://www.chiark.greenend.org.uk/~sgtatham/doit/
- win32yank (Windows)
- *win32yank* (Windows)
- putclip, getclip (Windows) https://cygwin.com/packages/summary/cygutils.html
- clip, powershell (Windows) https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/clip
- termux (via termux-clipboard-set, termux-clipboard-set)

View File

@ -1317,9 +1317,117 @@ g:compiler_gcc_ignore_unmatched_lines
JAVAC *compiler-javac*
Commonly used compiler options can be added to 'makeprg' by setting the
g:javac_makeprg_params variable. For example: >
b/g:javac_makeprg_params variable. For example: >
let g:javac_makeprg_params = "-Xlint:all -encoding utf-8"
<
MAVEN *compiler-maven*
Commonly used compiler options can be added to 'makeprg' by setting the
b/g:maven_makeprg_params variable. For example: >
let g:maven_makeprg_params = "-DskipTests -U -X"
SPOTBUGS *compiler-spotbugs*
SpotBugs is a static analysis tool that can be used to find bugs in Java.
It scans the Java bytecode of all classes in the currently open buffer.
(Therefore, `:compiler! spotbugs` is not supported.)
Commonly used compiler options can be added to 'makeprg' by setting the
"b:" or "g:spotbugs_makeprg_params" variable. For example: >
let b:spotbugs_makeprg_params = "-longBugCodes -effort:max -low"
The global default is "-workHard -experimental".
By default, the class files are searched in the directory where the source
files are placed. However, typical Java projects use distinct directories
for source files and class files. To make both known to SpotBugs, assign
their paths (distinct and relative to their common root directory) to the
following properties (using the example of a common Maven project): >
let g:spotbugs_properties = {
\ 'sourceDirPath': 'src/main/java',
\ 'classDirPath': 'target/classes',
\ 'testSourceDirPath': 'src/test/java',
\ 'testClassDirPath': 'target/test-classes',
\ }
Note that values for the path keys describe only for SpotBugs where to look
for files; refer to the documentation for particular compiler plugins for more
information.
The default pre- and post-compiler actions are provided for Ant, Maven, and
Javac compiler plugins and can be selected by assigning the name of a compiler
plugin to the "compiler" key: >
let g:spotbugs_properties = {
\ 'compiler': 'maven',
\ }
This single setting is essentially equivalent to all the settings below, with
the exception made for the "PreCompilerAction" and "PreCompilerTestAction"
values: their listed |Funcref|s will obtain no-op implementations whereas the
implicit Funcrefs of the "compiler" key will obtain the requested defaults if
available. >
let g:spotbugs_properties = {
\ 'PreCompilerAction':
\ function('spotbugs#DefaultPreCompilerAction'),
\ 'PreCompilerTestAction':
\ function('spotbugs#DefaultPreCompilerTestAction'),
\ 'PostCompilerAction':
\ function('spotbugs#DefaultPostCompilerAction'),
\ 'sourceDirPath': 'src/main/java',
\ 'classDirPath': 'target/classes',
\ 'testSourceDirPath': 'src/test/java',
\ 'testClassDirPath': 'target/test-classes',
\ }
With default actions, the compiler of choice will attempt to rebuild the class
files for the buffer (and possibly for the whole project) as soon as a Java
syntax file is loaded; then, `spotbugs` will attempt to analyze the quality of
the compilation unit of the buffer.
When default actions are not suited to a desired workflow, consider writing
arbitrary functions yourself and matching their |Funcref|s to the supported
keys: "PreCompilerAction", "PreCompilerTestAction", and "PostCompilerAction".
The next example re-implements the default pre-compiler actions for a Maven
project and requests other default Maven settings with the "compiler" entry: >
function! MavenPreCompilerAction() abort
call spotbugs#DeleteClassFiles()
compiler maven
make compile
endfunction
function! MavenPreCompilerTestAction() abort
call spotbugs#DeleteClassFiles()
compiler maven
make test-compile
endfunction
let g:spotbugs_properties = {
\ 'compiler': 'maven',
\ 'PreCompilerAction':
\ function('MavenPreCompilerAction'),
\ 'PreCompilerTestAction':
\ function('MavenPreCompilerTestAction'),
\ }
Note that all entered custom settings will take precedence over the matching
default settings in "g:spotbugs_properties".
The "g:spotbugs_properties" variable is consulted by the Java filetype plugin
(|ft-java-plugin|) to arrange for the described automation, and, therefore, it
must be defined before |FileType| events can take place for the buffers loaded
with Java source files. It could, for example, be set in a project-local
|vimrc| loaded by [0].
[0] https://github.com/MarcWeber/vim-addon-local-vimrc/
GNU MAKE *compiler-make*
Since the default make program is "make", the compiler plugin for make,
@ -1409,6 +1517,13 @@ Useful values for the 'makeprg' options therefore are:
setlocal makeprg=./alltests.py " Run a testsuite
setlocal makeprg=python\ %:S " Run a single testcase
PYTEST COMPILER *compiler-pytest*
Commonly used compiler options can be added to 'makeprg' by setting the
b/g:pytest_makeprg_params variable. For example: >
let b:pytest_makeprg_params = "--verbose --no-summary --disable-warnings"
The global default is "--tb=short --quiet"; Python warnings are suppressed.
TEX COMPILER *compiler-tex*

View File

@ -10,7 +10,7 @@ Sign Support Features *sign-support*
Type |gO| to see the table of contents.
==============================================================================
1. Introduction *sign-intro* *signs*
1. Introduction *sign-intro* *signs* *gutter*
When a debugger or other IDE tool is driving an editor it needs to be able
to give specific highlights which quickly tell the user useful information

View File

@ -414,12 +414,15 @@ There are many types of assembly languages that all use the same file name
extensions. Therefore you will have to select the type yourself, or add a
line in the assembly file that Vim will recognize. Currently these syntax
files are included:
asm GNU assembly (the default)
asm GNU assembly (usually have .s or .S extension and were
already built using C compiler such as GCC or CLANG)
asm68k Motorola 680x0 assembly
asmh8300 Hitachi H-8300 version of GNU assembly
ia64 Intel Itanium 64
fasm Flat assembly (https://flatassembler.net)
masm Microsoft assembly (probably works for any 80x86)
masm Microsoft assembly (.masm files are compiled with
Microsoft's Macro Assembler. This is only supported
for x86, x86_64, ARM and AARCH64 CPU families)
nasm Netwide assembly
tasm Turbo Assembly (with opcodes 80x86 up to Pentium, and
MMX)
@ -5159,8 +5162,6 @@ EndOfBuffer Filler lines (~) after the end of the buffer.
By default, this is highlighted like |hl-NonText|.
*hl-TermCursor*
TermCursor Cursor in a focused terminal.
*hl-TermCursorNC*
TermCursorNC Cursor in an unfocused terminal.
*hl-ErrorMsg*
ErrorMsg Error messages on the command line.
*hl-WinSeparator*
@ -5242,6 +5243,8 @@ PmenuMatch Popup menu: Matched text in normal item. Combined with
*hl-PmenuMatchSel*
PmenuMatchSel Popup menu: Matched text in selected item. Combined with
|hl-PmenuMatch| and |hl-PmenuSel|.
*hl-ComplMatchIns*
ComplMatchIns Matched text of the currently inserted completion.
*hl-Question*
Question |hit-enter| prompt and yes/no questions.
*hl-QuickFixLine*

View File

@ -26,7 +26,7 @@ Start *terminal-start*
There are several ways to create a terminal buffer:
- Run the |:terminal| command.
- Call the |nvim_open_term()| or |termopen()| function.
- Call |nvim_open_term()| or `jobstart(…, {'term': v:true})`.
- Edit a "term://" buffer. Examples: >vim
:edit term://bash
:vsplit term://top
@ -101,13 +101,17 @@ Configuration *terminal-config*
Options: 'modified', 'scrollback'
Events: |TermOpen|, |TermEnter|, |TermLeave|, |TermClose|
Highlight groups: |hl-TermCursor|, |hl-TermCursorNC|
Highlight groups: |hl-TermCursor|
Terminal sets local defaults for some options, which may differ from your
global configuration.
- 'list' is disabled
- 'wrap' is disabled
- 'number' is disabled
- 'relativenumber' is disabled
- 'signcolumn' is set to "no"
- 'foldcolumn' is set to "0"
You can change the defaults with a TermOpen autocommand: >vim
au TermOpen * setlocal list

View File

@ -245,15 +245,32 @@ The following directives are built in:
(#gsub! @_node ".*%.(.*)" "%1")
<
`trim!` *treesitter-directive-trim!*
Trim blank lines from the end of the node. This will set a new
`metadata[capture_id].range`.
Trims whitespace from the node. Sets a new
`metadata[capture_id].range`. Takes a capture ID and, optionally, four
integers to customize trimming behavior (`1` meaning trim, `0` meaning
don't trim). When only given a capture ID, trims blank lines (lines
that contain only whitespace, or are empty) from the end of the node
(for backwards compatibility). Can trim all whitespace from both sides
of the node if parameters are given.
Examples: >query
; only trim blank lines from the end of the node
; (equivalent to (#trim! @fold 0 0 1 0))
(#trim! @fold)
; trim blank lines from both sides of the node
(#trim! @fold 1 0 1 0)
; trim all whitespace around the node
(#trim! @fold 1 1 1 1)
<
Parameters: ~
{capture_id}
{trim_start_linewise}
{trim_start_charwise}
{trim_end_linewise} (default `1` if only given {capture_id})
{trim_end_charwise}
Example: >query
(#trim! @fold)
<
Further directives can be added via |vim.treesitter.query.add_directive()|.
Use |vim.treesitter.query.list_directives()| to list all available directives.
@ -885,8 +902,8 @@ get_captures_at_pos({bufnr}, {row}, {col})
Returns a list of highlight captures at the given position
Each capture is represented by a table containing the capture name as a
string as well as a table of metadata (`priority`, `conceal`, ...; empty
if none are defined).
string, the capture's language, a table of metadata (`priority`,
`conceal`, ...; empty if none are defined), and the id of the capture.
Parameters: ~
• {bufnr} (`integer`) Buffer number (0 for current buffer)
@ -894,7 +911,7 @@ get_captures_at_pos({bufnr}, {row}, {col})
• {col} (`integer`) Position column
Return: ~
(`{capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata}[]`)
(`{capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata, id: integer}[]`)
get_node({opts}) *vim.treesitter.get_node()*
Returns the smallest named node at the given position

View File

@ -788,7 +788,8 @@ must handle.
kind
Name indicating the message kind:
"" (empty) Unknown (consider a feature-request: |bugs|)
"" (empty) Unknown (consider a |feature-request|)
"bufwrite" |:write| message
"confirm" |confirm()| or |:confirm| dialog
"confirm_sub" |:substitute| confirm dialog |:s_c|
"emsg" Error (|errors|, internal error, |:throw|, …)
@ -804,6 +805,7 @@ must handle.
"quickfix" Quickfix navigation message
"search_cmd" Entered search command
"search_count" Search count message ("S" flag of 'shortmess')
"undo" |:undo| and |:redo| message
"wildlist" 'wildmode' "list" message
"wmsg" Warning ("search hit BOTTOM", |W10|, …)
New kinds may be added in the future; clients should treat unknown

View File

@ -534,7 +534,8 @@ gO Show a filetype-specific, navigable "outline" of the
current buffer. For example, in a |help| buffer this
shows the table of contents.
Currently works in |help| and |:Man| buffers.
Works in |help| and |:Man| buffers, or any buffer with
an active |LSP| client (|lsp-defaults|).
[N]gs *gs* *:sl* *:sleep*
:[N]sl[eep] [N][m] Do nothing for [N] seconds, or [N] milliseconds if [m]
@ -551,8 +552,7 @@ gO Show a filetype-specific, navigable "outline" of the
Queued messages are processed during the sleep.
*:sl!* *:sleep!*
:[N]sl[eep]! [N][m] Same as above. Unlike Vim, it does not hide the
cursor. |vim-differences|
:[N]sl[eep]! [N][m] Same as above, but hide the cursor.
==============================================================================
2. Using Vim like less or more *less*

View File

@ -0,0 +1,73 @@
*vietnamese.txt* Nvim
VIM REFERENCE MANUAL by Phạm Bình An
Type |gO| to see the table of contents.
===============================================================================
1. Introduction
*vietnamese-intro*
Vim supports Vietnamese language in the following ways:
- Built-in |vietnamese-keymap|, which allows you to type Vietnamese characters
in |Insert-mode| and |search-commands| using US keyboard layout.
- Localization in Vietnamese. See |vietnamese-l10n|
===============================================================================
2. Vietnamese keymaps
*vietnamese-keymap*
To switch between languages you can use your system native keyboard switcher,
or use one of the Vietnamese keymaps included in the Vim distribution, like
below >
:set keymap=vietnamese-telex_utf-8
<
See |'keymap'| for more information.
In the latter case, you can type Vietnamese even if you do not have a
Vietnamese input method engine (IME) or you want Vim to be independent from a
system-wide keyboard settings (when |'imdisable'| is set). You can also |:map|
a key to switch between keyboards.
Vim comes with the following Vietnamese keymaps:
- *vietnamese-telex_utf-8* Telex input method, |UTF-8| encoding.
- *vietnamese-viqr_utf-8* VIQR input method, |UTF-8| encoding.
- *vietnamese-vni_utf-8* VNI input method, |UTF-8| encoding.
*vietnamese-ime_diff*
Since these keymaps were designed to be minimalistic, they do not support all
features of the corresponding input methods. The differences are described
below:
- You can only type each character individually, entering the base letter first
and then the diacritics later. For example, to type the word `nến` using
|vietnamese-vni_utf-8|, you must type `ne61n`, not `nen61` or `ne6n1`
- For characters with more than 1 diacritic, you need to type vowel mark before
tone mark. For example, to type `ồ` using |vietnamese-telex_utf-8|, you need
to type `oof`, not `ofo`.
- With |vietnamese-telex_utf-8|, you need to type all uppercase letters to
produce uppercase characters with diacritics. For example, `Ừ` must be typed
as `UWF`.
- With |vietnamese-telex_utf-8|, the escape character `\` from VNI is added,
hence the confusing `ooo` input to type `oo` is removed, which could lead to
ambiguities. For example, to type the word `Đoòng`, you would type
`DDo\ofng`.
- Simple Telex (both v1 and v2), including the `w[]{}` style, is not
supported.
- Removing diacritics using `z` in Telex or `0` in VNI and VIQR is not supported.
===============================================================================
3. Localization
*vietnamese-l10n*
Vim |messages| are also available in Vietnamese. If you wish to see messages
in Vietnamese, you can run the command |:language| with an argument being the
name of the Vietnamese locale. For example, >
:language vi_VN
< or >
:language vi_VN.utf-8
<
Note that the name of the Vietnamese locale may vary depending on your system.
See |mbyte-first| for details.
===============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -39,7 +39,6 @@ Defaults *nvim-defaults*
- 'autoindent' is enabled
- 'autoread' is enabled (works in all UIs, including terminal)
- 'background' defaults to "dark" (unless set automatically by the terminal/UI)
- 'backspace' defaults to "indent,eol,start"
- 'backupdir' defaults to .,~/.local/state/nvim/backup// (|xdg|), auto-created
- 'belloff' defaults to "all"
- 'comments' includes "fb:•"
@ -187,6 +186,10 @@ nvim_terminal:
- 'textwidth' set to 0
- 'nowrap'
- 'nolist'
- 'nonumber'
- 'norelativenumber'
- 'signcolumn' set to "no"
- 'foldcolumn' set to "0"
- 'winhighlight' uses |hl-StatusLineTerm| and |hl-StatusLineTermNC| in
place of |hl-StatusLine| and |hl-StatusLineNC|
@ -322,7 +325,6 @@ Highlight groups:
- |hl-MsgSeparator| highlights separator for scrolled messages
- |hl-Substitute|
- |hl-TermCursor|
- |hl-TermCursorNC|
- |hl-WinSeparator| highlights window separators
- |hl-Whitespace| highlights 'listchars' whitespace
- |hl-WinBar| highlights 'winbar'
@ -667,7 +669,6 @@ Commands:
- :promptrepl
- :scriptversion (always version 1)
- :shell
- :sleep! (does not hide the cursor; same as :sleep)
- :smile
- :tearoff
- :cstag
@ -687,7 +688,7 @@ Cscope:
https://github.com/dhananjaylatkar/cscope_maps.nvim
Eval:
- Vim9script
- *Vim9script* (the Vim 9+ flavor of Vimscript) is not supported.
- *cscope_connection()*
- *err_teapot()*
- *js_encode()*

View File

@ -189,6 +189,8 @@ v:event
changing window (or tab) on |DirChanged|.
status Job status or exit code, -1 means "unknown". |TermClose|
reason Reason for completion being done. |CompleteDone|
complete_word The word that was selected, empty if abandoned complete.
complete_type See |complete_info_mode|
*v:exception* *exception-variable*
v:exception

View File

@ -978,6 +978,13 @@ CTRL-W g } *CTRL-W_g}*
it. Make the new Preview window (if required) N high. If N is
not given, 'previewheight' is used.
*:pb* *:pbuffer*
:[N]pb[uffer][!] [+cmd] [N]
Edit buffer [N] from the buffer list in the preview window.
If [N] is not given, the current buffer remains being edited.
See |:buffer-!| for [!]. This will also edit a buffer that is
not in the buffer list, without setting the 'buflisted' flag.
*:ped* *:pedit*
:ped[it][!] [++opt] [+cmd] {file}
Edit {file} in the preview window. The preview window is
@ -985,6 +992,8 @@ CTRL-W g } *CTRL-W_g}*
position isn't changed. Useful example: >
:pedit +/fputc /usr/include/stdio.h
<
Also see |++opt| and |+cmd|.
*:ps* *:psearch*
:[range]ps[earch][!] [count] [/]pattern[/]
Works like |:ijump| but shows the found match in the preview

View File

@ -13,8 +13,8 @@ vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'StdinReadPost' }, {
end
local ft, on_detect = vim.filetype.match({
-- The unexpanded file name is needed here. #27914
-- Neither args.file nor args.match are guaranteed to be unexpanded.
filename = vim.fn.bufname(args.buf),
-- However, bufname() can't be used, as it doesn't work with :doautocmd. #31306
filename = args.file,
buf = args.buf,
})
if not ft then

View File

@ -3,7 +3,7 @@
" Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com>
" Former Maintainer: Dan Sharp
" Repository: https://github.com/zzzyxwvut/java-vim.git
" Last Change: 2024 Sep 26
" Last Change: 2024 Nov 24
" 2024 Jan 14 by Vim Project (browsefilter)
" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
@ -90,10 +90,127 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
endif
endif
" The support for pre- and post-compiler actions for SpotBugs.
if exists("g:spotbugs_properties") && has_key(g:spotbugs_properties, 'compiler')
try
let spotbugs#compiler = g:spotbugs_properties.compiler
let g:spotbugs_properties = extend(
\ spotbugs#DefaultProperties(),
\ g:spotbugs_properties,
\ 'force')
catch
echomsg v:errmsg
finally
call remove(g:spotbugs_properties, 'compiler')
endtry
endif
if exists("g:spotbugs_properties") &&
\ filereadable($VIMRUNTIME . '/compiler/spotbugs.vim')
let s:request = 0
if has_key(g:spotbugs_properties, 'PreCompilerAction')
let s:dispatcher = 'call g:spotbugs_properties.PreCompilerAction() | '
let s:request += 1
endif
if has_key(g:spotbugs_properties, 'PreCompilerTestAction')
let s:dispatcher = 'call g:spotbugs_properties.PreCompilerTestAction() | '
let s:request += 2
endif
if has_key(g:spotbugs_properties, 'PostCompilerAction')
let s:request += 4
endif
if (s:request == 3 || s:request == 7) &&
\ has_key(g:spotbugs_properties, 'sourceDirPath') &&
\ has_key(g:spotbugs_properties, 'testSourceDirPath')
function! s:DispatchAction(path_action_pairs) abort
let name = expand('%:p')
for [path, Action] in a:path_action_pairs
if name =~# (path . '.\{-}\.java\=$')
call Action()
break
endif
endfor
endfunction
let s:dispatcher = printf('call s:DispatchAction(%s) | ',
\ string([[g:spotbugs_properties.sourceDirPath,
\ g:spotbugs_properties.PreCompilerAction],
\ [g:spotbugs_properties.testSourceDirPath,
\ g:spotbugs_properties.PreCompilerTestAction]]))
endif
if s:request
if exists("b:spotbugs_syntax_once")
let s:actions = [{'event': 'BufWritePost'}]
else
" XXX: Handle multiple FileType events when vimrc contains more
" than one filetype setting for the language, e.g.:
" :filetype plugin indent on
" :autocmd BufRead,BufNewFile *.java setlocal filetype=java ...
" XXX: DO NOT ADD b:spotbugs_syntax_once TO b:undo_ftplugin !
let b:spotbugs_syntax_once = 1
let s:actions = [{
\ 'event': 'Syntax',
\ 'once': 1,
\ }, {
\ 'event': 'BufWritePost',
\ }]
endif
for s:idx in range(len(s:actions))
if s:request == 7 || s:request == 6 || s:request == 5
let s:actions[s:idx].cmd = s:dispatcher . 'compiler spotbugs | ' .
\ 'call g:spotbugs_properties.PostCompilerAction()'
elseif s:request == 4
let s:actions[s:idx].cmd = 'compiler spotbugs | ' .
\ 'call g:spotbugs_properties.PostCompilerAction()'
elseif s:request == 3 || s:request == 2 || s:request == 1
let s:actions[s:idx].cmd = s:dispatcher . 'compiler spotbugs'
else
let s:actions[s:idx].cmd = ''
endif
endfor
if !exists("#java_spotbugs")
augroup java_spotbugs
augroup END
endif
" The events are defined in s:actions.
silent! autocmd! java_spotbugs BufWritePost <buffer>
silent! autocmd! java_spotbugs Syntax <buffer>
for s:action in s:actions
execute printf('autocmd java_spotbugs %s <buffer> %s',
\ s:action.event,
\ s:action.cmd . (has_key(s:action, 'once')
\ ? printf(' | autocmd! java_spotbugs %s <buffer>',
\ s:action.event)
\ : ''))
endfor
unlet! s:action s:actions s:idx s:dispatcher
endif
unlet s:request
endif
function! JavaFileTypeCleanUp() abort
setlocal suffixes< suffixesadd< formatoptions< comments< commentstring< path< includeexpr<
unlet! b:browsefilter
" The concatenated removals may be misparsed as a BufWritePost autocmd.
silent! autocmd! java_spotbugs BufWritePost <buffer>
silent! autocmd! java_spotbugs Syntax <buffer>
endfunction
" Undo the stuff we changed.
let b:undo_ftplugin = "setlocal suffixes< suffixesadd<" .
\ " formatoptions< comments< commentstring< path< includeexpr<" .
\ " | unlet! b:browsefilter"
let b:undo_ftplugin = 'call JavaFileTypeCleanUp() | delfunction JavaFileTypeCleanUp'
" See ":help vim9-mix".
if !has("vim9script")
@ -114,6 +231,19 @@ if exists("s:zip_func_upgradable")
setlocal suffixesadd<
endif
if exists("*s:DispatchAction")
def! s:DispatchAction(path_action_pairs: list<list<any>>)
const name: string = expand('%:p')
for [path: string, Action: func: any] in path_action_pairs
if name =~# (path .. '.\{-}\.java\=$')
Action()
break
endif
endfor
enddef
endif
" Restore the saved compatibility options.
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@ -0,0 +1,18 @@
" Vim filetype plugin
" Language: Protobuf
" Maintainer: David Pedersen <limero@me.com>
" Last Change: 2024 Dec 09
if exists('b:did_ftplugin')
finish
endif
let b:did_ftplugin = 1
setlocal formatoptions-=t formatoptions+=croql
setlocal comments=s1:/*,mb:*,ex:*/,://
setlocal commentstring=//\ %s
let b:undo_ftplugin = "setlocal formatoptions< comments< commentstring<"
" vim: sw=2 sts=2 et

16
runtime/ftplugin/ptx.vim Normal file
View File

@ -0,0 +1,16 @@
" Vim filetype plugin file
" Language: Nvidia PTX (Parellel Thread Execution)
" Maintainer: Yinzuo Jiang <jiangyinzuo@foxmail.com>
" Last Change: 2024-12-05
if exists("b:did_ftplugin")
finish
endif
let b:did_ftplugin = 1
" Comments in PTX follow C/C++ syntax
" See: https://docs.nvidia.com/cuda/parallel-thread-execution/#syntax
setlocal commentstring=//\ %s
let b:undo_ftplugin = 'setl commentstring<'

View File

@ -3,8 +3,9 @@
" Maintainer: Tom Picton <tom@tompicton.com>
" Previous Maintainer: James Sully <sullyj3@gmail.com>
" Previous Maintainer: Johannes Zellner <johannes@zellner.org>
" Last Change: 2024/05/13
" https://github.com/tpict/vim-ftplugin-python
" Repository: https://github.com/tpict/vim-ftplugin-python
" Last Change: 2024/05/13
" 2024 Nov 30 use pytest compiler (#16130)
if exists("b:did_ftplugin") | finish | endif
let b:did_ftplugin = 1
@ -134,6 +135,11 @@ elseif executable('python')
setlocal keywordprg=python\ -m\ pydoc
endif
if expand('%:t') =~# '\v^test_.*\.py$|_test\.py$' && executable('pytest')
compiler pytest
let &l:makeprg .= ' %:S'
endif
" Script for filetype switching to undo the local stuff we may have changed
let b:undo_ftplugin = 'setlocal cinkeys<'
\ . '|setlocal comments<'
@ -148,6 +154,7 @@ let b:undo_ftplugin = 'setlocal cinkeys<'
\ . '|setlocal softtabstop<'
\ . '|setlocal suffixesadd<'
\ . '|setlocal tabstop<'
\ . '|setlocal makeprg<'
\ . '|silent! nunmap <buffer> [M'
\ . '|silent! nunmap <buffer> [['
\ . '|silent! nunmap <buffer> []'

View File

@ -1,7 +1,8 @@
" Vim filetype plugin file
" Language: Typst
" Maintainer: Gregory Anders
" Last Change: 2024 Oct 21
" Previous Maintainer: Gregory Anders
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
" Last Change: 2024 Dec 09
" Based on: https://github.com/kaarmu/typst.vim
if exists('b:did_ftplugin')
@ -11,10 +12,14 @@ let b:did_ftplugin = 1
setlocal commentstring=//\ %s
setlocal comments=s1:/*,mb:*,ex:*/,://
setlocal formatoptions+=croq
setlocal formatoptions+=croqn
" Numbered Lists
setlocal formatlistpat=^\\s*\\d\\+[\\]:.)}\\t\ ]\\s*
" Unordered (-), Ordered (+) and definition (/) Lists
setlocal formatlistpat+=\\\|^\\s*[-+/\]\\s\\+
setlocal suffixesadd=.typ
let b:undo_ftplugin = 'setl cms< com< fo< sua<'
let b:undo_ftplugin = 'setl cms< com< fo< flp< sua<'
if get(g:, 'typst_conceal', 0)
setlocal conceallevel=2

View File

@ -1,7 +1,8 @@
" Vim indent file
" Language: Typst
" Maintainer: Gregory Anders <greg@gpanders.com>
" Last Change: 2024-07-14
" Previous Maintainer: Gregory Anders
" Maintainer: Luca Saccarola <github.e41mv@aleeas.com>
" Last Change: 2024 Dec 09
" Based on: https://github.com/kaarmu/typst.vim
if exists('b:did_indent')

View File

@ -21,9 +21,12 @@ end
local function system(cmd, silent, env)
local r = vim.system(cmd, { env = env, timeout = 10000 }):wait()
if r.code ~= 0 and not silent then
local cmd_str = table.concat(cmd, ' ')
man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
if not silent then
if r.code ~= 0 then
local cmd_str = table.concat(cmd, ' ')
man_error(string.format("command error '%s': %s", cmd_str, r.stderr))
end
assert(r.stdout ~= '')
end
return assert(r.stdout)

View File

@ -49,10 +49,10 @@ do
vim.keymap.set('x', '*', function()
return _visual_search('/')
end, { desc = ':help v_star-default', expr = true, silent = true })
end, { desc = ':help v_star-default', expr = true, replace_keycodes = false })
vim.keymap.set('x', '#', function()
return _visual_search('?')
end, { desc = ':help v_#-default', expr = true, silent = true })
end, { desc = ':help v_#-default', expr = true, replace_keycodes = false })
end
--- Map Y to y$. This mimics the behavior of D and C. See |Y-default|
@ -222,8 +222,8 @@ do
--- Execute a command and print errors without a stacktrace.
--- @param opts table Arguments to |nvim_cmd()|
local function cmd(opts)
local _, err = pcall(vim.api.nvim_cmd, opts, {})
if err then
local ok, err = pcall(vim.api.nvim_cmd, opts, {})
if not ok then
vim.api.nvim_err_writeln(err:sub(#'Vim:' + 1))
end
end
@ -435,7 +435,7 @@ do
group = nvim_terminal_augroup,
desc = 'Treat term:// buffers as terminal buffers',
nested = true,
command = "if !exists('b:term_title')|call termopen(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
command = "if !exists('b:term_title')|call jobstart(matchstr(expand(\"<amatch>\"), '\\c\\mterm://\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), {'term': v:true, 'cwd': expand(get(matchlist(expand(\"<amatch>\"), '\\c\\mterm://\\(.\\{-}\\)//'), 1, ''))})",
})
vim.api.nvim_create_autocmd({ 'TermClose' }, {
@ -492,6 +492,10 @@ do
vim.bo.textwidth = 0
vim.wo[0][0].wrap = false
vim.wo[0][0].list = false
vim.wo[0][0].number = false
vim.wo[0][0].relativenumber = false
vim.wo[0][0].signcolumn = 'no'
vim.wo[0][0].foldcolumn = '0'
-- This is gross. Proper list options support when?
local winhl = vim.o.winhighlight
@ -546,8 +550,9 @@ do
---
--- @param option string Option name
--- @param value any Option value
local function setoption(option, value)
if vim.api.nvim_get_option_info2(option, {}).was_set then
--- @param force boolean? Always set the value, even if already set
local function setoption(option, value, force)
if not force and vim.api.nvim_get_option_info2(option, {}).was_set then
-- Don't do anything if option is already set
return
end
@ -563,7 +568,7 @@ do
once = true,
nested = true,
callback = function()
setoption(option, value)
setoption(option, value, force)
end,
})
end
@ -645,11 +650,15 @@ do
return nil, nil, nil
end
local timer = assert(vim.uv.new_timer())
-- This autocommand updates the value of 'background' anytime we receive
-- an OSC 11 response from the terminal emulator. If the user has set
-- 'background' explictly then we will delete this autocommand,
-- effectively disabling automatic background setting.
local force = false
local id = vim.api.nvim_create_autocmd('TermResponse', {
group = group,
nested = true,
desc = "Update the value of 'background' automatically based on the terminal emulator's background color",
callback = function(args)
local resp = args.data ---@type string
local r, g, b = parseosc11(resp)
@ -661,27 +670,33 @@ do
if rr and gg and bb then
local luminance = (0.299 * rr) + (0.587 * gg) + (0.114 * bb)
local bg = luminance < 0.5 and 'dark' or 'light'
setoption('background', bg)
end
setoption('background', bg, force)
return true
-- On the first query response, don't force setting the option in
-- case the user has already set it manually. If they have, then
-- this autocommand will be deleted. If they haven't, then we do
-- want to force setting the option to override the value set by
-- this autocommand.
if not force then
force = true
end
end
end
end,
})
vim.api.nvim_create_autocmd('VimEnter', {
group = group,
nested = true,
once = true,
callback = function()
if vim.api.nvim_get_option_info2('background', {}).was_set then
vim.api.nvim_del_autocmd(id)
end
end,
})
io.stdout:write('\027]11;?\007')
timer:start(1000, 0, function()
-- Delete the autocommand if no response was received
vim.schedule(function()
-- Suppress error if autocommand has already been deleted
pcall(vim.api.nvim_del_autocmd, id)
end)
if not timer:is_closing() then
timer:close()
end
end)
end
--- If the TUI (term_has_truecolor) was able to determine that the host

View File

@ -53,7 +53,7 @@ function vim.inspect_pos(bufnr, row, col, filter)
local cursor = vim.api.nvim_win_get_cursor(win)
row, col = cursor[1] - 1, cursor[2]
end
bufnr = bufnr == 0 and vim.api.nvim_get_current_buf() or bufnr
bufnr = vim._resolve_bufnr(bufnr)
local results = {
treesitter = {}, --- @type table[]
@ -146,6 +146,13 @@ end
---
---Can also be shown with `:Inspect`. [:Inspect]()
---
---Example: To bind this function to the vim-scriptease
---inspired `zS` in Normal mode:
---
---```lua
---vim.keymap.set('n', 'zS', vim.show_pos)
---```
---
---@since 11
---@param bufnr? integer defaults to the current buffer
---@param row? integer row to inspect, 0-based. Defaults to the row of the current cursor
@ -171,7 +178,7 @@ function vim.show_pos(bufnr, row, col, filter)
if data.hl_group ~= data.hl_group_link then
append('links to ', 'MoreMsg')
append(data.hl_group_link, data.hl_group_link)
append(' ')
append(' ')
end
if comment then
append(comment, 'Comment')
@ -184,7 +191,14 @@ function vim.show_pos(bufnr, row, col, filter)
append('Treesitter', 'Title')
nl()
for _, capture in ipairs(items.treesitter) do
item(capture, capture.lang)
item(
capture,
string.format(
'priority: %d language: %s',
capture.metadata.priority or vim.hl.priorities.treesitter,
capture.lang
)
)
end
nl()
end

View File

@ -272,12 +272,12 @@ function vim.api.nvim_buf_attach(buffer, send_buffer, opts) end
--- This temporarily switches current buffer to "buffer".
--- If the current window already shows "buffer", the window is not switched.
--- If a window inside the current tabpage (including a float) already shows the
--- buffer, then one of these windows will be set as current window temporarily.
--- buffer, then one of those windows will be set as current window temporarily.
--- Otherwise a temporary scratch window (called the "autocmd window" for
--- historical reasons) will be used.
---
--- This is useful e.g. to call Vimscript functions that only work with the
--- current buffer/window currently, like `termopen()`.
--- current buffer/window currently, like `jobstart(…, {'term': v:true})`.
---
--- @param buffer integer Buffer handle, or 0 for current buffer
--- @param fun function Function to call inside the buffer (currently Lua callable
@ -885,10 +885,8 @@ function vim.api.nvim_cmd(cmd, opts) end
---
--- On execution error: fails with Vimscript error, updates v:errmsg.
---
--- Prefer using `nvim_cmd()` or `nvim_exec2()` over this. To evaluate multiple lines of Vim script
--- or an Ex command directly, use `nvim_exec2()`. To construct an Ex command using a structured
--- format and then execute it, use `nvim_cmd()`. To modify an Ex command before evaluating it, use
--- `nvim_parse_cmd()` in conjunction with `nvim_cmd()`.
--- Prefer `nvim_cmd()` or `nvim_exec2()` instead. To modify an Ex command in a structured way
--- before executing it, modify the result of `nvim_parse_cmd()` then pass it to `nvim_cmd()`.
---
--- @param command string Ex command string
function vim.api.nvim_command(command) end
@ -963,9 +961,9 @@ function vim.api.nvim_create_augroup(name, opts) end
--- - id: (number) autocommand id
--- - event: (string) name of the triggered event `autocmd-events`
--- - group: (number|nil) autocommand group id, if any
--- - match: (string) expanded value of [<amatch>]
--- - buf: (number) expanded value of [<abuf>]
--- - file: (string) expanded value of [<afile>]
--- - file: (string) [<afile>] (not expanded to a full path)
--- - match: (string) [<amatch>] (expanded to a full path)
--- - buf: (number) [<abuf>]
--- - data: (any) arbitrary data passed from [nvim_exec_autocmds()] [event-data]()
--- - command (string) optional: Vim command to execute on event. Cannot be used with
--- {callback}
@ -1012,7 +1010,7 @@ function vim.api.nvim_create_namespace(name) end
--- ```
---
--- @param name string Name of the new user command. Must begin with an uppercase letter.
--- @param command any Replacement command to execute when this user command is executed. When called
--- @param command string|fun(args: vim.api.keyset.create_user_command.command_args) Replacement command to execute when this user command is executed. When called
--- from Lua, the command can also be a Lua function. The function is called with a
--- single table argument that contains the following keys:
--- - name: (string) Command name
@ -1654,7 +1652,7 @@ function vim.api.nvim_notify(msg, log_level, opts) end
--- Open a terminal instance in a buffer
---
--- By default (and currently the only option) the terminal will not be
--- connected to an external process. Instead, input send on the channel
--- connected to an external process. Instead, input sent on the channel
--- will be echoed directly by the terminal. This is useful to display
--- ANSI terminal sequences returned as part of a rpc message, or similar.
---
@ -1665,6 +1663,18 @@ function vim.api.nvim_notify(msg, log_level, opts) end
--- Then `nvim_chan_send()` can be called immediately to process sequences
--- in a virtual terminal having the intended size.
---
--- Example: this `TermHl` command can be used to display and highlight raw ANSI termcodes, so you
--- can use Nvim as a "scrollback pager" (for terminals like kitty): [terminal-scrollback-pager]()
---
--- ```lua
--- vim.api.nvim_create_user_command('TermHl', function()
--- local b = vim.api.nvim_create_buf(false, true)
--- local chan = vim.api.nvim_open_term(b, {})
--- vim.api.nvim_chan_send(chan, table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), '\n'))
--- vim.api.nvim_win_set_buf(0, b)
--- end, { desc = 'Highlights ANSI termcodes in curbuf' })
--- ```
---
--- @param buffer integer the buffer to use (expected to be empty)
--- @param opts vim.api.keyset.open_term Optional parameters.
--- - on_input: Lua callback for input sent, i e keypresses in terminal

View File

@ -4,11 +4,11 @@
error('Cannot require a meta file')
--- @class vim.api.keyset.buf_attach
--- @field on_lines? function
--- @field on_bytes? function
--- @field on_changedtick? function
--- @field on_detach? function
--- @field on_reload? function
--- @field on_lines? fun(_: "lines", bufnr: integer, changedtick: integer, first: integer, last_old: integer, last_new: integer, byte_count: integer, deleted_codepoints?: integer, deleted_codeunits?: integer): boolean?
--- @field on_bytes? fun(_: "bytes", bufnr: integer, changedtick: integer, start_row: integer, start_col: integer, start_byte: integer, old_end_row: integer, old_end_col: integer, old_end_byte: integer, new_end_row: integer, new_end_col: integer, new_end_byte: integer): boolean?
--- @field on_changedtick? fun(_: "changedtick", bufnr: integer, changedtick: integer)
--- @field on_detach? fun(_: "detach", bufnr: integer)
--- @field on_reload? fun(_: "reload", bufnr: integer)
--- @field utf_sizes? boolean
--- @field preview? boolean
@ -18,9 +18,9 @@ error('Cannot require a meta file')
--- @class vim.api.keyset.clear_autocmds
--- @field buffer? integer
--- @field event? any
--- @field group? any
--- @field pattern? any
--- @field event? string|string[]
--- @field group? integer|string
--- @field pattern? string|string[]
--- @class vim.api.keyset.cmd
--- @field cmd? string
@ -28,12 +28,12 @@ error('Cannot require a meta file')
--- @field count? integer
--- @field reg? string
--- @field bang? boolean
--- @field args? any[]
--- @field args? string[]
--- @field magic? table<string,any>
--- @field mods? table<string,any>
--- @field nargs? any
--- @field addr? any
--- @field nextcmd? any
--- @field nargs? integer|string
--- @field addr? string
--- @field nextcmd? string
--- @class vim.api.keyset.cmd_magic
--- @field file? boolean
@ -72,20 +72,20 @@ error('Cannot require a meta file')
--- @field info? string
--- @class vim.api.keyset.context
--- @field types? any[]
--- @field types? string[]
--- @class vim.api.keyset.create_augroup
--- @field clear? any
--- @field clear? boolean
--- @class vim.api.keyset.create_autocmd
--- @field buffer? integer
--- @field callback? any
--- @field callback? string|(fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?)
--- @field command? string
--- @field desc? string
--- @field group? any
--- @field group? integer|string
--- @field nested? boolean
--- @field once? boolean
--- @field pattern? any
--- @field pattern? string|string[]
--- @class vim.api.keyset.echo_opts
--- @field verbose? boolean
@ -103,19 +103,19 @@ error('Cannot require a meta file')
--- @class vim.api.keyset.exec_autocmds
--- @field buffer? integer
--- @field group? any
--- @field group? integer|string
--- @field modeline? boolean
--- @field pattern? any
--- @field pattern? string|string[]
--- @field data? any
--- @class vim.api.keyset.exec_opts
--- @field output? boolean
--- @class vim.api.keyset.get_autocmds
--- @field event? any
--- @field group? any
--- @field pattern? any
--- @field buffer? any
--- @field event? string|string[]
--- @field group? integer|string
--- @field pattern? string|string[]
--- @field buffer? integer|integer[]
--- @class vim.api.keyset.get_commands
--- @field builtin? boolean
@ -154,17 +154,17 @@ error('Cannot require a meta file')
--- @field altfont? boolean
--- @field nocombine? boolean
--- @field default? boolean
--- @field cterm? any
--- @field foreground? any
--- @field fg? any
--- @field background? any
--- @field bg? any
--- @field ctermfg? any
--- @field ctermbg? any
--- @field special? any
--- @field sp? any
--- @field link? any
--- @field global_link? any
--- @field cterm? integer|string
--- @field foreground? integer|string
--- @field fg? integer|string
--- @field background? integer|string
--- @field bg? integer|string
--- @field ctermfg? integer|string
--- @field ctermbg? integer|string
--- @field special? integer|string
--- @field sp? integer|string
--- @field link? integer|string
--- @field global_link? integer|string
--- @field fallback? boolean
--- @field blend? integer
--- @field fg_indexed? boolean
@ -201,7 +201,7 @@ error('Cannot require a meta file')
--- @field wins? any[]
--- @class vim.api.keyset.open_term
--- @field on_input? function
--- @field on_input? fun(_: "input", term: integer, bufnr: integer, data: any)
--- @field force_crlf? boolean
--- @class vim.api.keyset.option
@ -227,20 +227,20 @@ error('Cannot require a meta file')
--- @field do_source? boolean
--- @class vim.api.keyset.set_decoration_provider
--- @field on_start? function
--- @field on_buf? function
--- @field on_win? function
--- @field on_line? function
--- @field on_end? function
--- @field _on_hl_def? function
--- @field _on_spell_nav? function
--- @field on_start? fun(_: "start", tick: integer)
--- @field on_buf? fun(_: "buf", bufnr: integer, tick: integer)
--- @field on_win? fun(_: "win", winid: integer, bufnr: integer, toprow: integer, botrow: integer)
--- @field on_line? fun(_: "line", winid: integer, bufnr: integer, row: integer)
--- @field on_end? fun(_: "end", tick: integer)
--- @field _on_hl_def? fun(_: "hl_def")
--- @field _on_spell_nav? fun(_: "spell_nav")
--- @class vim.api.keyset.set_extmark
--- @field id? integer
--- @field end_line? integer
--- @field end_row? integer
--- @field end_col? integer
--- @field hl_group? number|string
--- @field hl_group? integer|string
--- @field virt_text? any[]
--- @field virt_text_pos? string
--- @field virt_text_win_col? integer
@ -258,10 +258,10 @@ error('Cannot require a meta file')
--- @field virt_lines_leftcol? boolean
--- @field strict? boolean
--- @field sign_text? string
--- @field sign_hl_group? number|string
--- @field number_hl_group? number|string
--- @field line_hl_group? number|string
--- @field cursorline_hl_group? number|string
--- @field sign_hl_group? integer|string
--- @field number_hl_group? integer|string
--- @field line_hl_group? integer|string
--- @field cursorline_hl_group? integer|string
--- @field conceal? string
--- @field spell? boolean
--- @field ui_watched? boolean
@ -292,7 +292,7 @@ error('Cannot require a meta file')
--- @field relative? string
--- @field split? string
--- @field win? integer
--- @field bufpos? any[]
--- @field bufpos? integer[]
--- @field external? boolean
--- @field focusable? boolean
--- @field mouse? boolean
@ -315,12 +315,12 @@ error('Cannot require a meta file')
--- @field end_vcol? integer
--- @class vim.api.keyset.xdl_diff
--- @field on_hunk? function
--- @field on_hunk? fun(start_a: integer, count_a: integer, start_b: integer, count_b: integer): integer?
--- @field result_type? string
--- @field algorithm? string
--- @field ctxlen? integer
--- @field interhunkctxlen? integer
--- @field linematch? any
--- @field linematch? boolean|integer
--- @field ignore_whitespace? boolean
--- @field ignore_whitespace_change? boolean
--- @field ignore_whitespace_change_at_eol? boolean

View File

@ -73,6 +73,51 @@ error('Cannot require a meta file')
--- @field buflocal? boolean
--- @field buffer? integer
--- @class vim.api.keyset.create_autocmd.callback_args
--- @field id integer autocommand id
--- @field event string name of the triggered event |autocmd-events|
--- @field group? integer autocommand group id, if any
--- @field match string expanded value of <amatch>
--- @field buf integer expanded value of <abuf>
--- @field file string expanded value of <afile>
--- @field data? any arbitrary data passed from |nvim_exec_autocmds()| *event-data*
--- @class vim.api.keyset.create_user_command.command_args
--- @field name string Command name
---
--- The args passed to the command, if any <args>
--- @field args string
---
--- The args split by unescaped whitespace
--- (when more than one argument is allowed), if any <f-args>
--- @field fargs string[]
---
--- Number of arguments |:command-nargs|
--- @field nargs string
---
--- "true" if the command was executed with a ! modifier <bang>
--- @field bang boolean
---
--- The starting line of the command range <line1>
--- @field line1 integer
---
--- The final line of the command range <line2>
--- @field line2 integer
---
--- The number of items in the command range: 0, 1, or 2 <range>
--- @field range integer
---
--- Any count supplied <count>
--- @field count integer
--- The optional register, if specified <reg>
--- @field reg string
--- Command modifiers, if any <mods>
--- @field mods string
---
--- Command modifiers in a structured format. Has the same structure as the
--- "mods" key of |nvim_parse_cmd()|.
--- @field smods table
--- @class vim.api.keyset.command_info
--- @field name string
--- @field definition string
@ -114,6 +159,7 @@ error('Cannot require a meta file')
--- @field bg? integer
--- @field sp? integer
--- @field default? true
--- @field link? string
--- @field blend? integer
--- @field cterm? vim.api.keyset.hl_info.cterm

View File

@ -35,5 +35,8 @@ function vim.json.decode(str, opts) end
--- Encodes (or "packs") Lua object {obj} as JSON in a Lua string.
---@param obj any
---@param opts? table<string,any> Options table with keys:
--- - escape_slash: (boolean) (default false) When true, escapes `/`
--- character in JSON strings
---@return string
function vim.json.encode(obj) end
function vim.json.encode(obj, opts) end

View File

@ -1086,9 +1086,9 @@ vim.go.cia = vim.go.completeitemalign
--- a match from the menu. Only works in combination with
--- "menu" or "menuone". No effect if "longest" is present.
---
--- noselect Do not select a match in the menu, force the user to
--- select one from the menu. Only works in combination with
--- "menu" or "menuone".
--- noselect Same as "noinsert", except that no menu item is
--- pre-selected. If both "noinsert" and "noselect" are present,
--- "noselect" has precedence.
---
--- fuzzy Enable `fuzzy-matching` for completion candidates. This
--- allows for more flexible and intuitive matching, where
@ -2783,6 +2783,7 @@ vim.go.gp = vim.go.grepprg
--- ci Command-line Insert mode
--- cr Command-line Replace mode
--- sm showmatch in Insert mode
--- t Terminal mode
--- a all modes
--- The argument-list is a dash separated list of these arguments:
--- hor{N} horizontal bar, {N} percent of the character height
@ -2802,7 +2803,8 @@ vim.go.gp = vim.go.grepprg
--- ```vim
--- set guicursor=n:blinkon0
--- ```
--- - Default is "blinkon0" for each mode.
---
--- Default is "blinkon0" for each mode.
--- {group-name}
--- Highlight group that decides the color and font of the
--- cursor.
@ -2848,7 +2850,7 @@ vim.go.gp = vim.go.grepprg
---
---
--- @type string
vim.o.guicursor = "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"
vim.o.guicursor = "n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20,t:block-blinkon500-blinkoff500-TermCursor"
vim.o.gcr = vim.o.guicursor
vim.go.guicursor = vim.o.guicursor
vim.go.gcr = vim.go.guicursor
@ -3016,7 +3018,7 @@ vim.go.hid = vim.go.hidden
--- A history of ":" commands, and a history of previous search patterns
--- is remembered. This option decides how many entries may be stored in
--- each of these histories (see `cmdline-editing` and 'msghistory' for
--- each of these histories (see `cmdline-editing` and 'messagesopt' for
--- the number of messages to remember).
--- The maximum value is 10000.
---
@ -4084,6 +4086,31 @@ vim.o.mis = vim.o.menuitems
vim.go.menuitems = vim.o.menuitems
vim.go.mis = vim.go.menuitems
--- Option settings for outputting messages. It can consist of the
--- following items. Items must be separated by a comma.
---
--- hit-enter Use a `hit-enter` prompt when the message is longer than
--- 'cmdheight' size.
---
--- wait:{n} Instead of using a `hit-enter` prompt, simply wait for
--- {n} milliseconds so that the user has a chance to read
--- the message. The maximum value of {n} is 10000. Use
--- 0 to disable the wait (but then the user may miss an
--- important message).
--- This item is ignored when "hit-enter" is present, but
--- required when "hit-enter" is not present.
---
--- history:{n} Determines how many entries are remembered in the
--- `:messages` history. The maximum value is 10000.
--- Setting it to zero clears the message history.
--- This item must always be present.
---
--- @type string
vim.o.messagesopt = "hit-enter,history:500"
vim.o.mopt = vim.o.messagesopt
vim.go.messagesopt = vim.o.messagesopt
vim.go.mopt = vim.go.messagesopt
--- Parameters for `:mkspell`. This tunes when to start compressing the
--- word tree. Compression can be slow when there are many words, but
--- it's needed to avoid running out of memory. The amount of memory used
@ -4379,16 +4406,6 @@ vim.o.mouset = vim.o.mousetime
vim.go.mousetime = vim.o.mousetime
vim.go.mouset = vim.go.mousetime
--- Determines how many entries are remembered in the `:messages` history.
--- The maximum value is 10000.
--- Setting it to zero clears the message history.
---
--- @type integer
vim.o.msghistory = 500
vim.o.mhi = vim.o.msghistory
vim.go.msghistory = vim.o.msghistory
vim.go.mhi = vim.go.msghistory
--- This defines what bases Vim will consider for numbers when using the
--- CTRL-A and CTRL-X commands for adding to and subtracting from a number
--- respectively; see `CTRL-A` for more info on these commands.
@ -4995,6 +5012,7 @@ vim.go.ruf = vim.go.rulerformat
--- indent/ indent scripts `indent-expression`
--- keymap/ key mapping files `mbyte-keymap`
--- lang/ menu translations `:menutrans`
--- lsp/ LSP client configurations `lsp-config`
--- lua/ `Lua` plugins
--- menu.vim GUI menus `menu.vim`
--- pack/ packages `:packadd`
@ -5198,6 +5216,8 @@ vim.go.sect = vim.go.sections
--- selection.
--- When "old" is used and 'virtualedit' allows the cursor to move past
--- the end of line the line break still isn't included.
--- When "exclusive" is used, cursor position in visual mode will be
--- adjusted for inclusive motions `inclusive-motion-selection-exclusive`.
--- Note that when "exclusive" is used and selecting from the end
--- backwards, you cannot include the last character of a line, when
--- starting in Normal mode and 'virtualedit' empty.
@ -6311,6 +6331,7 @@ vim.wo.stc = vim.wo.statuscolumn
--- All fields except the {item} are optional. A single percent sign can
--- be given as "%%".
---
--- *stl-%!*
--- When the option starts with "%!" then it is used as an expression,
--- evaluated and the result is used as the option value. Example:
---

View File

@ -1147,8 +1147,9 @@ function vim.fn.confirm(msg, choices, default, type) end
--- A |Dictionary| is copied in a similar way as a |List|.
--- Also see |deepcopy()|.
---
--- @param expr any
--- @return any
--- @generic T
--- @param expr T
--- @return T
function vim.fn.copy(expr) end
--- Return the cosine of {expr}, measured in radians, as a |Float|.
@ -1228,7 +1229,7 @@ function vim.fn.ctxpush(types) end
---
--- @param context table
--- @param index? integer
--- @return any
--- @return integer
function vim.fn.ctxset(context, index) end
--- Returns the size of the |context-stack|.
@ -1308,9 +1309,10 @@ function vim.fn.debugbreak(pid) end
--- {noref} set to 1 will fail.
--- Also see |copy()|.
---
--- @param expr any
--- @generic T
--- @param expr T
--- @param noref? boolean
--- @return any
--- @return T
function vim.fn.deepcopy(expr, noref) end
--- Without {flags} or with {flags} empty: Deletes the file by the
@ -1421,7 +1423,7 @@ function vim.fn.dictwatcherdel(dict, pattern, callback) end
--- editing another buffer to set 'filetype' and load a syntax
--- file.
---
--- @return any
--- @return integer
function vim.fn.did_filetype() end
--- Returns the number of filler lines above line {lnum}.
@ -1433,7 +1435,7 @@ function vim.fn.did_filetype() end
--- Returns 0 if the current window is not in diff mode.
---
--- @param lnum integer
--- @return any
--- @return integer
function vim.fn.diff_filler(lnum) end
--- Returns the highlight ID for diff mode at line {lnum} column
@ -1468,7 +1470,7 @@ function vim.fn.diff_hlID(lnum, col) end
--- <
---
--- @param chars string
--- @return any
--- @return string
function vim.fn.digraph_get(chars) end
--- Return a list of digraphs. If the {listall} argument is given
@ -1486,7 +1488,7 @@ function vim.fn.digraph_get(chars) end
--- <
---
--- @param listall? boolean
--- @return any
--- @return string[][]
function vim.fn.digraph_getlist(listall) end
--- Add digraph {chars} to the list. {chars} must be a string
@ -1538,7 +1540,7 @@ function vim.fn.digraph_setlist(digraphlist) end
--- - A |Blob| is empty when its length is zero.
---
--- @param expr any
--- @return any
--- @return integer
function vim.fn.empty(expr) end
--- Return all of environment variables as dictionary. You can
@ -1561,7 +1563,7 @@ function vim.fn.environ() end
---
--- @param string string
--- @param chars string
--- @return any
--- @return string
function vim.fn.escape(string, chars) end
--- Evaluate {string} and return the result. Especially useful to
@ -2368,7 +2370,7 @@ function vim.fn.foldtextresult(lnum) end
---
--- @param expr1 string|table
--- @param expr2 string|function
--- @return any
--- @return string|table
function vim.fn.foreach(expr1, expr2) end
--- Get the full command name from a short abbreviated command
@ -2675,7 +2677,7 @@ function vim.fn.getbufinfo(dict) end
--- @param buf integer|string
--- @param lnum integer
--- @param end_? integer
--- @return any
--- @return string[]
function vim.fn.getbufline(buf, lnum, end_) end
--- Just like `getbufline()` but only get one line and return it
@ -2943,7 +2945,7 @@ function vim.fn.getcmdprompt() end
--- Also see |getcmdpos()|, |setcmdpos()|, |getcmdline()| and
--- |setcmdline()|.
---
--- @return any
--- @return integer
function vim.fn.getcmdscreenpos() end
--- Return the current command-line type. Possible return values
@ -3869,7 +3871,7 @@ function vim.fn.gettagstack(winnr) end
--- strings.
---
--- @param text string
--- @return any
--- @return string
function vim.fn.gettext(text) end
--- Returns information about windows as a |List| with Dictionaries.
@ -3885,6 +3887,8 @@ function vim.fn.gettext(text) end
--- botline last complete displayed buffer line
--- bufnr number of buffer in the window
--- height window height (excluding winbar)
--- leftcol first column displayed; only used when
--- 'wrap' is off
--- loclist 1 if showing a location list
--- quickfix 1 if quickfix or location list window
--- terminal 1 if a terminal window
@ -4018,7 +4022,7 @@ function vim.fn.glob(expr, nosuf, list, alllinks) end
--- a backslash usually means a path separator.
---
--- @param string string
--- @return any
--- @return string
function vim.fn.glob2regpat(string) end
--- Perform glob() for String {expr} on all directories in {path}
@ -4352,7 +4356,7 @@ function vim.fn.hostname() end
--- @param string string
--- @param from string
--- @param to string
--- @return any
--- @return string
function vim.fn.iconv(string, from, to) end
--- Returns a |String| which is a unique identifier of the
@ -4372,7 +4376,7 @@ function vim.fn.iconv(string, from, to) end
--- reuse identifiers of the garbage-collected ones.
---
--- @param expr any
--- @return any
--- @return string
function vim.fn.id(expr) end
--- The result is a Number, which is indent of line {lnum} in the
@ -4416,7 +4420,7 @@ function vim.fn.indent(lnum) end
--- @param expr any
--- @param start? integer
--- @param ic? boolean
--- @return any
--- @return integer
function vim.fn.index(object, expr, start, ic) end
--- Returns the index of an item in {object} where {expr} is
@ -4460,14 +4464,14 @@ function vim.fn.index(object, expr, start, ic) end
--- @param object any
--- @param expr any
--- @param opts? table
--- @return any
--- @return integer
function vim.fn.indexof(object, expr, opts) end
---
--- @param prompt string
--- @param text? string
--- @param completion? string
--- @return any
--- @return string
function vim.fn.input(prompt, text, completion) end
--- The result is a String, which is whatever the user typed on
@ -4581,7 +4585,7 @@ function vim.fn.input(prompt, text, completion) end
--- <
---
--- @param opts table
--- @return any
--- @return string
function vim.fn.input(opts) end
--- @deprecated
@ -4616,7 +4620,7 @@ function vim.fn.inputlist(textlist) end
--- called. Calling it more often is harmless though.
--- Returns TRUE when there is nothing to restore, FALSE otherwise.
---
--- @return any
--- @return integer
function vim.fn.inputrestore() end
--- Preserve typeahead (also from mappings) and clear it, so that
@ -4626,7 +4630,7 @@ function vim.fn.inputrestore() end
--- many inputrestore() calls.
--- Returns TRUE when out of memory, FALSE otherwise.
---
--- @return any
--- @return integer
function vim.fn.inputsave() end
--- This function acts much like the |input()| function with but
@ -4641,7 +4645,7 @@ function vim.fn.inputsave() end
---
--- @param prompt string
--- @param text? string
--- @return any
--- @return string
function vim.fn.inputsecret(prompt, text) end
--- When {object} is a |List| or a |Blob| insert {item} at the start
@ -4687,8 +4691,8 @@ function vim.fn.interrupt() end
--- let bits = invert(bits)
--- <
---
--- @param expr number
--- @return any
--- @param expr integer
--- @return integer
function vim.fn.invert(expr) end
--- The result is a Number, which is |TRUE| when {path} is an
@ -4767,7 +4771,7 @@ function vim.fn.isnan(expr) end
--- cases, items() returns a List with the index and the value at
--- the index.
---
--- @param dict any
--- @param dict table
--- @return any
function vim.fn.items(dict) end
@ -4801,7 +4805,7 @@ function vim.fn.jobresize(job, width, height) end
--- @return any
function vim.fn.jobsend(...) end
--- Note: Prefer |vim.system()| in Lua (unless using the `pty` option).
--- Note: Prefer |vim.system()| in Lua (unless using `rpc`, `pty`, or `term`).
---
--- Spawns {cmd} as a job.
--- If {cmd} is a List it runs directly (no 'shell').
@ -4875,6 +4879,10 @@ function vim.fn.jobsend(...) end
--- stdin: (string) Either "pipe" (default) to connect the
--- job's stdin to a channel or "null" to disconnect
--- stdin.
--- term: (boolean) Spawns {cmd} in a new pseudo-terminal session
--- connected to the current (unmodified) buffer. Implies "pty".
--- Default "height" and "width" are set to the current window
--- dimensions. |jobstart()|. Defaults $TERM to "xterm-256color".
--- width: (number) Width of the `pty` terminal.
---
--- {opts} is passed as |self| dictionary to the callback; the
@ -4888,7 +4896,7 @@ function vim.fn.jobsend(...) end
---
--- @param cmd string|string[]
--- @param opts? table
--- @return any
--- @return integer
function vim.fn.jobstart(cmd, opts) end
--- Stop |job-id| {id} by sending SIGTERM to the job process. If
@ -4901,7 +4909,7 @@ function vim.fn.jobstart(cmd, opts) end
--- exited or stopped.
---
--- @param id integer
--- @return any
--- @return integer
function vim.fn.jobstop(id) end
--- Waits for jobs and their |on_exit| handlers to complete.
@ -4926,7 +4934,7 @@ function vim.fn.jobstop(id) end
---
--- @param jobs integer[]
--- @param timeout? integer
--- @return any
--- @return integer[]
function vim.fn.jobwait(jobs, timeout) end
--- Join the items in {list} together into one String.
@ -4941,7 +4949,7 @@ function vim.fn.jobwait(jobs, timeout) end
---
--- @param list any[]
--- @param sep? string
--- @return any
--- @return string
function vim.fn.join(list, sep) end
--- Convert {expr} from JSON object. Accepts |readfile()|-style
@ -4974,14 +4982,14 @@ function vim.fn.json_decode(expr) end
--- |Blob|s are converted to arrays of the individual bytes.
---
--- @param expr any
--- @return any
--- @return string
function vim.fn.json_encode(expr) end
--- Return a |List| with all the keys of {dict}. The |List| is in
--- arbitrary order. Also see |items()| and |values()|.
---
--- @param dict table
--- @return any
--- @return string[]
function vim.fn.keys(dict) end
--- Turn the internal byte representation of keys into a form that
@ -4991,7 +4999,7 @@ function vim.fn.keys(dict) end
--- < <C-Home>
---
--- @param string string
--- @return any
--- @return string
function vim.fn.keytrans(string) end
--- @deprecated
@ -5010,8 +5018,8 @@ function vim.fn.last_buffer_nr() end
--- |Dictionary| is returned.
--- Otherwise an error is given and returns zero.
---
--- @param expr any
--- @return any
--- @param expr any[]
--- @return integer
function vim.fn.len(expr) end
--- Call function {funcname} in the run-time library {libname}
@ -5122,7 +5130,7 @@ function vim.fn.line2byte(lnum) end
--- When {lnum} is invalid, -1 is returned.
---
--- @param lnum integer
--- @return any
--- @return integer
function vim.fn.lispindent(lnum) end
--- Return a Blob concatenating all the number values in {list}.
@ -5135,7 +5143,7 @@ function vim.fn.lispindent(lnum) end
--- |blob2list()| does the opposite.
---
--- @param list any[]
--- @return any
--- @return string
function vim.fn.list2blob(list) end
--- Convert each number in {list} to a character string can
@ -5155,13 +5163,13 @@ function vim.fn.list2blob(list) end
---
--- @param list any[]
--- @param utf8? boolean
--- @return any
--- @return string
function vim.fn.list2str(list, utf8) end
--- Return the current time, measured as seconds since 1st Jan
--- 1970. See also |strftime()|, |strptime()| and |getftime()|.
---
--- @return any
--- @return integer
function vim.fn.localtime() end
--- Return the natural logarithm (base e) of {expr} as a |Float|.
@ -5175,7 +5183,7 @@ function vim.fn.localtime() end
--- < 5.0
---
--- @param expr number
--- @return any
--- @return number
function vim.fn.log(expr) end
--- Return the logarithm of Float {expr} to base 10 as a |Float|.
@ -5188,7 +5196,7 @@ function vim.fn.log(expr) end
--- < -2.0
---
--- @param expr number
--- @return any
--- @return number
function vim.fn.log10(expr) end
--- {expr1} must be a |List|, |String|, |Blob| or |Dictionary|.
@ -5950,7 +5958,7 @@ function vim.fn.matchstrpos(expr, pat, start, count) end
--- an error. An empty |List| or |Dictionary| results in zero.
---
--- @param expr any
--- @return any
--- @return number
function vim.fn.max(expr) end
--- Returns a |List| of |Dictionaries| describing |menus| (defined
@ -6088,7 +6096,7 @@ function vim.fn.menu_info(name, mode) end
--- an error. An empty |List| or |Dictionary| results in zero.
---
--- @param expr any
--- @return any
--- @return number
function vim.fn.min(expr) end
--- Create directory {name}.
@ -6133,7 +6141,7 @@ function vim.fn.min(expr) end
--- @param name string
--- @param flags? string
--- @param prot? string
--- @return any
--- @return integer
function vim.fn.mkdir(name, flags, prot) end
--- Return a string that indicates the current mode.
@ -6296,7 +6304,7 @@ function vim.fn.msgpackparse(data) end
--- See also |prevnonblank()|.
---
--- @param lnum integer
--- @return any
--- @return integer
function vim.fn.nextnonblank(lnum) end
--- Return a string with a single character, which has the number
@ -6315,7 +6323,7 @@ function vim.fn.nextnonblank(lnum) end
---
--- @param expr integer
--- @param utf8? boolean
--- @return any
--- @return string
function vim.fn.nr2char(expr, utf8) end
--- Bitwise OR on the two arguments. The arguments are converted
@ -6349,7 +6357,7 @@ vim.fn['or'] = function(expr, expr1) end
---
--- @param path string
--- @param len? integer
--- @return any
--- @return string
function vim.fn.pathshorten(path, len) end
--- Evaluate |perl| expression {expr} and return its result
@ -6383,7 +6391,7 @@ function vim.fn.perleval(expr) end
---
--- @param x number
--- @param y number
--- @return any
--- @return number
function vim.fn.pow(x, y) end
--- Return the line number of the first line at or above {lnum}
@ -6395,7 +6403,7 @@ function vim.fn.pow(x, y) end
--- Also see |nextnonblank()|.
---
--- @param lnum integer
--- @return any
--- @return integer
function vim.fn.prevnonblank(lnum) end
--- Return a String with {fmt}, where "%" items are replaced by
@ -7014,10 +7022,11 @@ function vim.fn.readfile(fname, type, max) end
--- echo reduce('xyz', { acc, val -> acc .. ',' .. val })
--- <
---
--- @generic T
--- @param object any
--- @param func function
--- @param func fun(accumulator: T, current: any): any
--- @param initial? any
--- @return any
--- @return T
function vim.fn.reduce(object, func, initial) end
--- Returns the single letter name of the register being executed.
@ -7170,7 +7179,7 @@ function vim.fn.remove(dict, key) end
---
--- @param from string
--- @param to string
--- @return any
--- @return integer
function vim.fn.rename(from, to) end
--- Repeat {expr} {count} times and return the concatenated
@ -7200,7 +7209,7 @@ vim.fn['repeat'] = function(expr, count) end
--- path name) and also keeps a trailing path separator.
---
--- @param filename string
--- @return any
--- @return string
function vim.fn.resolve(filename) end
--- Reverse the order of items in {object}. {object} can be a
@ -7213,8 +7222,9 @@ function vim.fn.resolve(filename) end
--- let revlist = reverse(copy(mylist))
--- <
---
--- @param object any
--- @return any
--- @generic T
--- @param object T[]
--- @return T[]
function vim.fn.reverse(object) end
--- Round off {expr} to the nearest integral value and return it
@ -7231,7 +7241,7 @@ function vim.fn.reverse(object) end
--- < -5.0
---
--- @param expr number
--- @return any
--- @return number
function vim.fn.round(expr) end
--- Sends {event} to {channel} via |RPC| and returns immediately.
@ -7242,9 +7252,9 @@ function vim.fn.round(expr) end
---
--- @param channel integer
--- @param event string
--- @param args? any
--- @return any
function vim.fn.rpcnotify(channel, event, args) end
--- @param ... any
--- @return integer
function vim.fn.rpcnotify(channel, event, ...) end
--- Sends a request to {channel} to invoke {method} via
--- |RPC| and blocks until a response is received.
@ -7254,9 +7264,9 @@ function vim.fn.rpcnotify(channel, event, args) end
---
--- @param channel integer
--- @param method string
--- @param args? any
--- @param ... any
--- @return any
function vim.fn.rpcrequest(channel, method, args) end
function vim.fn.rpcrequest(channel, method, ...) end
--- @deprecated
--- Deprecated. Replace >vim
@ -7300,7 +7310,7 @@ function vim.fn.rubyeval(expr) end
---
--- @param row integer
--- @param col integer
--- @return any
--- @return integer
function vim.fn.screenattr(row, col) end
--- The result is a Number, which is the character at position
@ -7314,7 +7324,7 @@ function vim.fn.screenattr(row, col) end
---
--- @param row integer
--- @param col integer
--- @return any
--- @return integer
function vim.fn.screenchar(row, col) end
--- The result is a |List| of Numbers. The first number is the same
@ -7325,7 +7335,7 @@ function vim.fn.screenchar(row, col) end
---
--- @param row integer
--- @param col integer
--- @return any
--- @return integer[]
function vim.fn.screenchars(row, col) end
--- The result is a Number, which is the current screen column of
@ -7342,7 +7352,7 @@ function vim.fn.screenchars(row, col) end
--- noremap GG <Cmd>echom screencol()<CR>
--- <
---
--- @return any
--- @return integer[]
function vim.fn.screencol() end
--- The result is a Dict with the screen position of the text
@ -7381,7 +7391,7 @@ function vim.fn.screenpos(winid, lnum, col) end
---
--- Note: Same restrictions as with |screencol()|.
---
--- @return any
--- @return integer
function vim.fn.screenrow() end
--- The result is a String that contains the base character and
@ -7393,7 +7403,7 @@ function vim.fn.screenrow() end
---
--- @param row integer
--- @param col integer
--- @return any
--- @return string
function vim.fn.screenstring(row, col) end
--- Search for regexp pattern {pattern}. The search starts at the
@ -7798,7 +7808,7 @@ function vim.fn.searchpos(pattern, flags, stopline, timeout, skip) end
--- echo serverlist()
--- <
---
--- @return any
--- @return string[]
function vim.fn.serverlist() end
--- Opens a socket or named pipe at {address} and listens for
@ -7835,7 +7845,7 @@ function vim.fn.serverlist() end
--- <
---
--- @param address? string
--- @return any
--- @return string
function vim.fn.serverstart(address) end
--- Closes the pipe or socket at {address}.
@ -7844,7 +7854,7 @@ function vim.fn.serverstart(address) end
--- address in |serverlist()|.
---
--- @param address string
--- @return any
--- @return integer
function vim.fn.serverstop(address) end
--- Set line {lnum} to {text} in buffer {buf}. This works like
@ -7874,7 +7884,7 @@ function vim.fn.serverstop(address) end
--- @param buf integer|string
--- @param lnum integer
--- @param text string|string[]
--- @return any
--- @return integer
function vim.fn.setbufline(buf, lnum, text) end
--- Set option or local variable {varname} in buffer {buf} to
@ -7979,7 +7989,7 @@ function vim.fn.setcharsearch(dict) end
---
--- @param str string
--- @param pos? integer
--- @return any
--- @return integer
function vim.fn.setcmdline(str, pos) end
--- Set the cursor position in the command line to byte position
@ -8289,7 +8299,7 @@ function vim.fn.setpos(expr, list) end
--- @param list vim.quickfix.entry[]
--- @param action? string
--- @param what? vim.fn.setqflist.what
--- @return any
--- @return integer
function vim.fn.setqflist(list, action, what) end
--- Set the register {regname} to {value}.
@ -8442,7 +8452,7 @@ function vim.fn.setwinvar(nr, varname, val) end
--- checksum of {string}.
---
--- @param string string
--- @return any
--- @return string
function vim.fn.sha256(string) end
--- Escape {string} for use as a shell command argument.
@ -8478,7 +8488,7 @@ function vim.fn.sha256(string) end
---
--- @param string string
--- @param special? boolean
--- @return any
--- @return string
function vim.fn.shellescape(string, special) end
--- Returns the effective value of 'shiftwidth'. This is the
@ -8930,7 +8940,7 @@ function vim.fn.sign_unplacelist(list) end
--- links before simplifying the path name, use |resolve()|.
---
--- @param filename string
--- @return any
--- @return string
function vim.fn.simplify(filename) end
--- Return the sine of {expr}, measured in radians, as a |Float|.
@ -8943,7 +8953,7 @@ function vim.fn.simplify(filename) end
--- < 0.763301
---
--- @param expr number
--- @return any
--- @return number
function vim.fn.sin(expr) end
--- Return the hyperbolic sine of {expr} as a |Float| in the range
@ -9077,10 +9087,11 @@ function vim.fn.sockconnect(mode, address, opts) end
--- eval mylist->sort({i1, i2 -> i1 - i2})
--- <
---
--- @param list any
--- @generic T
--- @param list T[]
--- @param how? string|function
--- @param dict? any
--- @return any
--- @return T[]
function vim.fn.sort(list, how, dict) end
--- Return the sound-folded equivalent of {word}. Uses the first
@ -9091,7 +9102,7 @@ function vim.fn.sort(list, how, dict) end
--- the method can be quite slow.
---
--- @param word string
--- @return any
--- @return string
function vim.fn.soundfold(word) end
--- Without argument: The result is the badly spelled word under
@ -9144,7 +9155,7 @@ function vim.fn.spellbadword(sentence) end
--- @param word string
--- @param max? integer
--- @param capital? boolean
--- @return any
--- @return string[]
function vim.fn.spellsuggest(word, max, capital) end
--- Make a |List| out of {string}. When {pattern} is omitted or
@ -9174,7 +9185,7 @@ function vim.fn.spellsuggest(word, max, capital) end
--- @param string string
--- @param pattern? string
--- @param keepempty? boolean
--- @return any
--- @return string[]
function vim.fn.split(string, pattern, keepempty) end
--- Return the non-negative square root of Float {expr} as a
@ -9326,6 +9337,7 @@ function vim.fn.str2float(string, quoted) end
--- and exists only for backwards-compatibility.
--- With UTF-8 composing characters are handled properly: >vim
--- echo str2list("á") " returns [97, 769]
--- <
---
--- @param string string
--- @param utf8? boolean
@ -10160,23 +10172,12 @@ function vim.fn.tanh(expr) end
--- @return string
function vim.fn.tempname() end
--- Spawns {cmd} in a new pseudo-terminal session connected
--- to the current (unmodified) buffer. Parameters and behavior
--- are the same as |jobstart()| except "pty", "width", "height",
--- and "TERM" are ignored: "height" and "width" are taken from
--- the current window. Note that termopen() implies a "pty" arg
--- to jobstart(), and thus has the implications documented at
--- |jobstart()|.
---
--- Returns the same values as jobstart().
---
--- Terminal environment is initialized as in |jobstart-env|,
--- except $TERM is set to "xterm-256color". Full behavior is
--- described in |terminal|.
--- @deprecated
--- Use |jobstart()| with `{term: v:true}` instead.
---
--- @param cmd string|string[]
--- @param opts? table
--- @return any
--- @return integer
function vim.fn.termopen(cmd, opts) end
--- Return a list with information about timers.
@ -10576,7 +10577,7 @@ function vim.fn.virtcol(expr, list, winid) end
--- @param winid integer
--- @param lnum integer
--- @param col integer
--- @return any
--- @return integer
function vim.fn.virtcol2col(winid, lnum, col) end
--- The result is a String, which describes the last Visual mode
@ -10597,7 +10598,7 @@ function vim.fn.virtcol2col(winid, lnum, col) end
--- the old value is returned. See |non-zero-arg|.
---
--- @param expr? boolean
--- @return any
--- @return string
function vim.fn.visualmode(expr) end
--- Waits until {condition} evaluates to |TRUE|, where {condition}
@ -10714,7 +10715,7 @@ function vim.fn.win_id2tabwin(expr) end
--- Return 0 if the window cannot be found in the current tabpage.
---
--- @param expr integer
--- @return any
--- @return integer
function vim.fn.win_id2win(expr) end
--- Move window {nr}'s vertical separator (i.e., the right border)
@ -10868,7 +10869,7 @@ function vim.fn.winheight(nr) end
--- <
---
--- @param tabnr? integer
--- @return any
--- @return any[]
function vim.fn.winlayout(tabnr) end
--- The result is a Number, which is the screen line of the cursor
@ -10912,7 +10913,7 @@ function vim.fn.winline() end
--- <
---
--- @param arg? string|integer
--- @return any
--- @return integer
function vim.fn.winnr(arg) end
--- Returns a sequence of |:resize| commands that should restore
@ -10925,7 +10926,7 @@ function vim.fn.winnr(arg) end
--- exe cmd
--- <
---
--- @return any
--- @return string
function vim.fn.winrestcmd() end
--- Uses the |Dictionary| returned by |winsaveview()| to restore
@ -10990,7 +10991,7 @@ function vim.fn.winsaveview() end
--- option.
---
--- @param nr integer
--- @return any
--- @return integer
function vim.fn.winwidth(nr) end
--- The result is a dictionary of byte/chars/word statistics for
@ -11075,7 +11076,7 @@ function vim.fn.writefile(object, fname, flags) end
--- let bits = xor(bits, 0x80)
--- <
---
--- @param expr number
--- @param expr1 number
--- @return any
--- @param expr integer
--- @param expr1 integer
--- @return integer
function vim.fn.xor(expr, expr1) end

View File

@ -15,7 +15,7 @@ vim.v.argv = ...
--- Argument for evaluating 'formatexpr' and used for the typed
--- character when using <expr> in an abbreviation `:map-<expr>`.
--- It is also used by the `InsertCharPre` and `InsertEnter` events.
--- @type any
--- @type string
vim.v.char = ...
--- The name of the character encoding of a file to be converted.
@ -60,7 +60,7 @@ vim.v.collate = ...
--- mode.
--- Note: Plugins can modify the value to emulate the builtin
--- `CompleteDone` event behavior.
--- @type any
--- @type vim.v.completed_item
vim.v.completed_item = ...
--- The count given for the last Normal mode command. Can be used
@ -90,7 +90,7 @@ vim.v.count1 = ...
--- This variable can not be set directly, use the `:language`
--- command.
--- See `multi-lang`.
--- @type any
--- @type string
vim.v.ctype = ...
--- Normally zero. When a deadly signal is caught it's set to
@ -197,7 +197,9 @@ vim.v.errors = ...
--- changing window (or tab) on `DirChanged`.
--- status Job status or exit code, -1 means "unknown". `TermClose`
--- reason Reason for completion being done. `CompleteDone`
--- @type any
--- complete_word The word that was selected, empty if abandoned complete.
--- complete_type See `complete_info_mode`
--- @type vim.v.event
vim.v.event = ...
--- The value of the exception most recently caught and not
@ -223,7 +225,7 @@ vim.v.exception = ...
--- ```vim
--- :au VimLeave * echo "Exit value is " .. v:exiting
--- ```
--- @type any
--- @type integer?
vim.v.exiting = ...
--- Special value used to put "false" in JSON and msgpack. See
@ -419,7 +421,7 @@ vim.v.mouse_winid = ...
--- and `msgpackdump()`. All types inside dictionary are fixed
--- (not editable) empty lists. To check whether some list is one
--- of msgpack types, use `is` operator.
--- @type any
--- @type table
vim.v.msgpack_types = ...
--- Special value used to put "null" in JSON and NIL in msgpack.
@ -563,7 +565,7 @@ vim.v.relnum = ...
--- typed command.
--- This can be used to find out why your script causes the
--- hit-enter prompt.
--- @type any
--- @type string
vim.v.scrollstart = ...
--- Search direction: 1 after a forward search, 0 after a
@ -705,13 +707,13 @@ vim.v.termrequest = ...
vim.v.termresponse = ...
--- Must be set before using `test_garbagecollect_now()`.
--- @type any
--- @type integer
vim.v.testing = ...
--- Full filename of the last loaded or saved session file.
--- Empty when no session file has been saved. See `:mksession`.
--- Modifiable (can be set).
--- @type any
--- @type string
vim.v.this_session = ...
--- The point where the exception most recently caught and not
@ -728,7 +730,7 @@ vim.v.this_session = ...
--- ```
---
--- Output: "Exception from test.vim, line 2"
--- @type any
--- @type string
vim.v.throwpoint = ...
--- Special value used to put "true" in JSON and msgpack. See

View File

@ -0,0 +1,77 @@
--- @meta _
error('Cannot require a meta file')
--- Extra types for vim.v dictionary fields
--- @class vim.v.completed_item
--- @field word? string the text that will be inserted, mandatory
--- abbreviation of "word"; when not empty it is used in the menu instead of "word"
--- @field abbr? string
--- extra text for the popup menu, displayed after "word" or "abbr"
--- @field menu? string
--- more information about the item, can be displayed in a preview window
--- @field info? string
--- @field kind? string single letter indicating the type of completion
--- when non-zero case is to be ignored when comparing items to be equal; when
--- omitted zero is used, thus items that only differ in case are added
--- @field icase? integer
--- when non-zero, always treat this item to be equal when comparing. Which
--- means, "equal=1" disables filtering of this item.
--- @field equal? integer
--- when non-zero this match will be added even when an item with the same word
--- is already present.
--- @field dup? integer
--- when non-zero this match will be added even when it is an empty string
--- @field empty? integer
--- custom data which is associated with the item and available
--- in |v:completed_item|; it can be any type; defaults to an empty string
--- @field user_data? any
--- an additional highlight group whose attributes are combined
--- with |hl-PmenuSel| and |hl-Pmenu| or |hl-PmenuMatchSel| and |hl-PmenuMatch|
--- highlight attributes in the popup menu to apply cterm and gui properties
--- (with higher priority) like strikethrough to the completion items abbreviation
--- @field abbr_hlgroup? string
--- an additional highlight group specifically for setting the highlight
--- attributes of the completion kind. When this field is present, it will
--- override the |hl-PmenuKind| highlight group, allowing for the customization
--- of ctermfg and guifg properties for the completion kind
--- @field kind_hlgroup? string
--- @class vim.v.event
--- Whether the event triggered during an aborting condition (e.g. |c_Esc| or
--- |c_CTRL-C| for |CmdlineLeave|).
--- @field abort? boolean
--- @field chan? integer See |channel-id|
--- @field info? table Dict of arbitrary event data.
--- @field cmdlevel? integer Level of cmdline.
--- @field cmdtype? string Type of cmdline, |cmdline-char|.
--- @field cwd? string Current working directory.
--- @field inclusive? boolean Motion is |inclusive|, else exclusive.
--- @field scope? string Event-specific scope name.
--- Current |operator|. Also set for Ex commands (unlike |v:operator|). For
--- example if |TextYankPost| is triggered by the |:yank| Ex command then
--- `v:event.operator` is "y".
--- @field operator? string
--- Text stored in the register as a |readfile()|-style list of lines.
--- @field regcontents? string
--- Requested register (e.g "x" for "xyy) or the empty string for an unnamed operation.
--- @field regname? string
--- @field regtype? string Type of register as returned by |getregtype()|.
--- @field visual? boolean Selection is visual (as opposed to, e.g., via motion).
--- @field completed_item? vim.v.completed_item
--- Current selected complete item on |CompleteChanged|, Is `{}` when no
--- complete item selected.
--- @field height? integer
--- @field width? integer Height of popup menu on |CompleteChanged|
--- @field row? integer Width of popup menu on |CompleteChanged|
--- Col count of popup menu on |CompleteChanged|, relative to screen.
--- @field col? integer
--- @field size? integer Total number of completion items on |CompleteChanged|.
--- Is |v:true| if popup menu have scrollbar, or |v:false| if not.
--- @field scrollbar? boolean
--- Is |v:true| if the event fired while changing window (or tab) on |DirChanged|.
--- @field changed_window? boolean
--- @field status? boolean Job status or exit code, -1 means "unknown". |TermClose|
--- @field reason? string Reason for completion being done. |CompleteDone|
--- The word that was selected, empty if abandoned complete. @field complete_word? string
--- @field complete_type? string See |complete_info_mode|

View File

@ -47,15 +47,6 @@ local function close_handle(handle)
end
end
---@param state vim.SystemState
local function close_handles(state)
close_handle(state.handle)
close_handle(state.stdin)
close_handle(state.stdout)
close_handle(state.stderr)
close_handle(state.timer)
end
--- @class vim.SystemObj
--- @field cmd string[]
--- @field pid integer
@ -132,9 +123,7 @@ function SystemObj:write(data)
-- (https://github.com/neovim/neovim/pull/17620#discussion_r820775616)
stdin:write('', function()
stdin:shutdown(function()
if stdin then
stdin:close()
end
close_handle(stdin)
end)
end)
end
@ -146,25 +135,52 @@ function SystemObj:is_closing()
return handle == nil or handle:is_closing() or false
end
---@param output fun(err:string?, data: string?)|false
---@return uv.uv_stream_t?
---@return fun(err:string?, data: string?)? Handler
local function setup_output(output)
if output == nil then
return assert(uv.new_pipe(false)), nil
--- @param output? uv.read_start.callback|false
--- @param text? boolean
--- @return uv.uv_stream_t? pipe
--- @return uv.read_start.callback? handler
--- @return string[]? data
local function setup_output(output, text)
if output == false then
return
end
local bucket --- @type string[]?
local handler --- @type uv.read_start.callback
if type(output) == 'function' then
return assert(uv.new_pipe(false)), output
handler = output
else
bucket = {}
handler = function(err, data)
if err then
error(err)
end
if text and data then
bucket[#bucket + 1] = data:gsub('\r\n', '\n')
else
bucket[#bucket + 1] = data
end
end
end
assert(output == false)
return nil, nil
local pipe = assert(uv.new_pipe(false))
--- @type uv.read_start.callback
local function handler_with_close(err, data)
handler(err, data)
if data == nil then
pipe:read_stop()
pipe:close()
end
end
return pipe, handler_with_close, bucket
end
---@param input string|string[]|true|nil
---@return uv.uv_stream_t?
---@return string|string[]?
--- @param input? string|string[]|boolean
--- @return uv.uv_stream_t?
--- @return string|string[]?
local function setup_input(input)
if not input then
return
@ -208,28 +224,6 @@ local function setup_env(env, clear_env)
return renv
end
--- @param stream uv.uv_stream_t
--- @param text? boolean
--- @param bucket string[]
--- @return fun(err: string?, data: string?)
local function default_handler(stream, text, bucket)
return function(err, data)
if err then
error(err)
end
if data ~= nil then
if text then
bucket[#bucket + 1] = data:gsub('\r\n', '\n')
else
bucket[#bucket + 1] = data
end
else
stream:read_stop()
stream:close()
end
end
end
local is_win = vim.fn.has('win32') == 1
local M = {}
@ -255,9 +249,9 @@ local function spawn(cmd, opts, on_exit, on_error)
return handle, pid_or_err --[[@as integer]]
end
---@param timeout integer
---@param cb fun()
---@return uv.uv_timer_t
--- @param timeout integer
--- @param cb fun()
--- @return uv.uv_timer_t
local function timer_oneshot(timeout, cb)
local timer = assert(uv.new_timer())
timer:start(timeout, 0, function()
@ -273,7 +267,12 @@ end
--- @param signal integer
--- @param on_exit fun(result: vim.SystemCompleted)?
local function _on_exit(state, code, signal, on_exit)
close_handles(state)
close_handle(state.handle)
close_handle(state.stdin)
close_handle(state.timer)
-- #30846: Do not close stdout/stderr here, as they may still have data to
-- read. They will be closed in uv.read_start on EOF.
local check = assert(uv.new_check())
check:start(function()
@ -311,6 +310,15 @@ local function _on_exit(state, code, signal, on_exit)
end)
end
--- @param state vim.SystemState
local function _on_error(state)
close_handle(state.handle)
close_handle(state.stdin)
close_handle(state.stdout)
close_handle(state.stderr)
close_handle(state.timer)
end
--- Run a system command
---
--- @param cmd string[]
@ -324,8 +332,8 @@ function M.run(cmd, opts, on_exit)
opts = opts or {}
local stdout, stdout_handler = setup_output(opts.stdout)
local stderr, stderr_handler = setup_output(opts.stderr)
local stdout, stdout_handler, stdout_data = setup_output(opts.stdout, opts.text)
local stderr, stderr_handler, stderr_data = setup_output(opts.stderr, opts.text)
local stdin, towrite = setup_input(opts.stdin)
--- @type vim.SystemState
@ -335,7 +343,9 @@ function M.run(cmd, opts, on_exit)
timeout = opts.timeout,
stdin = stdin,
stdout = stdout,
stdout_data = stdout_data,
stderr = stderr,
stderr_data = stderr_data,
}
--- @diagnostic disable-next-line:missing-fields
@ -350,17 +360,15 @@ function M.run(cmd, opts, on_exit)
}, function(code, signal)
_on_exit(state, code, signal, on_exit)
end, function()
close_handles(state)
_on_error(state)
end)
if stdout then
state.stdout_data = {}
stdout:read_start(stdout_handler or default_handler(stdout, opts.text, state.stdout_data))
if stdout and stdout_handler then
stdout:read_start(stdout_handler)
end
if stderr then
state.stderr_data = {}
stderr:read_start(stderr_handler or default_handler(stderr, opts.text, state.stderr_data))
if stderr and stderr_handler then
stderr:read_start(stderr_handler)
end
local obj = new_systemobj(state)

View File

@ -2,6 +2,20 @@ local api, if_nil = vim.api, vim.F.if_nil
local M = {}
--- @param title string
--- @return integer?
local function get_qf_id_for_title(title)
local lastqflist = vim.fn.getqflist({ nr = '$' })
for i = 1, lastqflist.nr do
local qflist = vim.fn.getqflist({ nr = i, id = 0, title = 0 })
if qflist.title == title then
return qflist.id
end
end
return nil
end
--- [diagnostic-structure]()
---
--- Diagnostics use the same indexing as the rest of the Nvim API (i.e. 0-based
@ -571,13 +585,6 @@ local underline_highlight_map = make_highlight_map('Underline')
local floating_highlight_map = make_highlight_map('Floating')
local sign_highlight_map = make_highlight_map('Sign')
local function get_bufnr(bufnr)
if not bufnr or bufnr == 0 then
return api.nvim_get_current_buf()
end
return bufnr
end
--- @param diagnostics vim.Diagnostic[]
--- @return table<integer,vim.Diagnostic[]>
local function diagnostic_lines(diagnostics)
@ -640,7 +647,7 @@ end
--- @param namespace integer
--- @param bufnr? integer
local function save_extmarks(namespace, bufnr)
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
if not diagnostic_attached_buffers[bufnr] then
api.nvim_buf_attach(bufnr, false, {
on_lines = function(_, _, _, _, _, last)
@ -812,7 +819,7 @@ local function get_diagnostics(bufnr, opts, clamp)
end
end
elseif namespace == nil then
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
for iter_namespace in pairs(diagnostic_cache[bufnr]) do
add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace])
end
@ -823,7 +830,7 @@ local function get_diagnostics(bufnr, opts, clamp)
end
end
else
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
for _, iter_namespace in ipairs(namespace) do
add_all_diags(bufnr, diagnostic_cache[bufnr][iter_namespace] or {})
end
@ -847,13 +854,33 @@ local function set_list(loclist, opts)
-- numbers beyond the end of the buffer
local diagnostics = get_diagnostics(bufnr, opts --[[@as vim.diagnostic.GetOpts]], false)
local items = M.toqflist(diagnostics)
local qf_id = nil
if loclist then
vim.fn.setloclist(winnr, {}, ' ', { title = title, items = items })
vim.fn.setloclist(winnr, {}, 'u', { title = title, items = items })
else
vim.fn.setqflist({}, ' ', { title = title, items = items })
qf_id = get_qf_id_for_title(title)
-- If we already have a diagnostics quickfix, update it rather than creating a new one.
-- This avoids polluting the finite set of quickfix lists, and preserves the currently selected
-- entry.
vim.fn.setqflist({}, qf_id and 'u' or ' ', {
title = title,
items = items,
id = qf_id,
})
end
if open then
api.nvim_command(loclist and 'lwindow' or 'botright cwindow')
if not loclist then
-- First navigate to the diagnostics quickfix list.
local nr = vim.fn.getqflist({ id = qf_id, nr = 0 }).nr
api.nvim_command(nr .. 'chistory')
-- Now open the quickfix list.
api.nvim_command('botright cwindow')
else
api.nvim_command('lwindow')
end
end
end
@ -1081,7 +1108,7 @@ function M.set(namespace, bufnr, diagnostics, opts)
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
vim.validate('opts', opts, 'table', true)
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
if vim.tbl_isempty(diagnostics) then
diagnostic_cache[bufnr][namespace] = nil
@ -1361,7 +1388,7 @@ M.handlers.signs = {
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
vim.validate('opts', opts, 'table', true)
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
opts = opts or {}
if not api.nvim_buf_is_loaded(bufnr) then
@ -1467,7 +1494,7 @@ M.handlers.underline = {
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
vim.validate('opts', opts, 'table', true)
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
opts = opts or {}
if not vim.api.nvim_buf_is_loaded(bufnr) then
@ -1531,7 +1558,7 @@ M.handlers.virtual_text = {
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
vim.validate('opts', opts, 'table', true)
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
opts = opts or {}
if not vim.api.nvim_buf_is_loaded(bufnr) then
@ -1656,7 +1683,7 @@ function M.hide(namespace, bufnr)
vim.validate('namespace', namespace, 'number', true)
vim.validate('bufnr', bufnr, 'number', true)
local buffers = bufnr and { get_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
local buffers = bufnr and { vim._resolve_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
for _, iter_bufnr in ipairs(buffers) do
local namespaces = namespace and { namespace } or vim.tbl_keys(diagnostic_cache[iter_bufnr])
for _, iter_namespace in ipairs(namespaces) do
@ -1683,7 +1710,7 @@ function M.is_enabled(filter)
return vim.tbl_isempty(diagnostic_disabled) and not diagnostic_disabled[1]
end
local bufnr = get_bufnr(filter.bufnr)
local bufnr = vim._resolve_bufnr(filter.bufnr)
if type(diagnostic_disabled[bufnr]) == 'table' then
return not diagnostic_disabled[bufnr][filter.ns_id]
end
@ -1724,7 +1751,7 @@ function M.show(namespace, bufnr, diagnostics, opts)
end
else
-- namespace is nil
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
for iter_namespace in pairs(diagnostic_cache[bufnr]) do
M.show(iter_namespace, bufnr, nil, opts)
end
@ -1791,7 +1818,7 @@ function M.open_float(opts, ...)
end
opts = opts or {}
bufnr = get_bufnr(bufnr or opts.bufnr)
bufnr = vim._resolve_bufnr(bufnr or opts.bufnr)
do
-- Resolve options with user settings from vim.diagnostic.config
@ -1962,6 +1989,7 @@ function M.open_float(opts, ...)
opts.focus_id = scope
end
local float_bufnr, winnr = vim.lsp.util.open_floating_preview(lines, 'plaintext', opts)
vim.bo[float_bufnr].path = vim.bo[bufnr].path
for i, hl in ipairs(highlights) do
local line = lines[i]
local prefix_len = hl.prefix and hl.prefix.length or 0
@ -1993,7 +2021,7 @@ function M.reset(namespace, bufnr)
vim.validate('namespace', namespace, 'number', true)
vim.validate('bufnr', bufnr, 'number', true)
local buffers = bufnr and { get_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
local buffers = bufnr and { vim._resolve_bufnr(bufnr) } or vim.tbl_keys(diagnostic_cache)
for _, iter_bufnr in ipairs(buffers) do
local namespaces = namespace and { namespace } or vim.tbl_keys(diagnostic_cache[iter_bufnr])
for _, iter_namespace in ipairs(namespaces) do
@ -2024,7 +2052,8 @@ end
--- (default: `true`)
--- @field open? boolean
---
--- Title of quickfix list. Defaults to "Diagnostics".
--- Title of quickfix list. Defaults to "Diagnostics". If there's already a quickfix list with this
--- title, it's updated. If not, a new quickfix list is created.
--- @field title? string
---
--- See |diagnostic-severity|.
@ -2131,7 +2160,7 @@ function M.enable(enable, filter)
ns.disabled = not enable
end
else
bufnr = get_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
if not ns_id then
diagnostic_disabled[bufnr] = (not enable) and true or nil
else

View File

@ -672,6 +672,7 @@ local extension = {
k = 'kwt',
ACE = 'lace',
ace = 'lace',
lalrpop = 'lalrpop',
latte = 'latte',
lte = 'latte',
ld = 'ld',
@ -743,6 +744,7 @@ local extension = {
mkd = detect.markdown,
markdown = detect.markdown,
mdown = detect.markdown,
masm = 'masm',
mhtml = 'mason',
mason = 'mason',
master = 'master',
@ -805,6 +807,7 @@ local extension = {
n1ql = 'n1ql',
nql = 'n1ql',
nanorc = 'nanorc',
nasm = 'nasm',
NSA = 'natural',
NSC = 'natural',
NSG = 'natural',
@ -958,11 +961,14 @@ local extension = {
ps1xml = 'ps1xml',
psf = 'psf',
psl = 'psl',
ptx = 'ptx',
pug = 'pug',
purs = 'purescript',
arr = 'pyret',
pxd = 'pyrex',
pxi = 'pyrex',
pyx = 'pyrex',
['pyx+'] = 'pyrex',
pyw = 'python',
py = 'python',
pyi = 'python',
@ -1869,8 +1875,11 @@ local filename = {
['.clangd'] = 'yaml',
['.clang-format'] = 'yaml',
['.clang-tidy'] = 'yaml',
['pixi.lock'] = 'yaml',
['yarn.lock'] = 'yaml',
matplotlibrc = 'yaml',
['.condarc'] = 'yaml',
condarc = 'yaml',
zathurarc = 'zathurarc',
['/etc/zprofile'] = 'zsh',
['.zlogin'] = 'zsh',

View File

@ -1,3 +1,15 @@
--- @brief <pre>help
--- *vim.fs.exists()*
--- Use |uv.fs_stat()| to check a file's type, and whether it exists.
---
--- Example:
---
--- >lua
--- if vim.uv.fs_stat(file) then
--- vim.print("file exists")
--- end
--- <
local uv = vim.uv
local M = {}

View File

@ -399,50 +399,57 @@ function M.reset(path)
end
end
--- Enables the experimental Lua module loader:
--- * overrides loadfile
--- Enables or disables the experimental Lua module loader:
---
--- Enable (`enable=true`):
--- * overrides |loadfile()|
--- * adds the Lua loader using the byte-compilation cache
--- * adds the libs loader
--- * removes the default Nvim loader
---
--- @since 0
function M.enable()
if M.enabled then
return
end
M.enabled = true
vim.fn.mkdir(vim.fn.fnamemodify(M.path, ':p'), 'p')
_G.loadfile = loadfile_cached
-- add Lua loader
table.insert(loaders, 2, loader_cached)
-- add libs loader
table.insert(loaders, 3, loader_lib_cached)
-- remove Nvim loader
for l, loader in ipairs(loaders) do
if loader == vim._load_package then
table.remove(loaders, l)
break
end
end
end
--- Disables the experimental Lua module loader:
--- Disable (`enable=false`):
--- * removes the loaders
--- * adds the default Nvim loader
---
--- @since 0
function M.disable()
if not M.enabled then
---
--- @param enable? (boolean) true/nil to enable, false to disable
function M.enable(enable)
enable = enable == nil and true or enable
if enable == M.enabled then
return
end
M.enabled = false
_G.loadfile = _loadfile
for l, loader in ipairs(loaders) do
if loader == loader_cached or loader == loader_lib_cached then
table.remove(loaders, l)
M.enabled = enable
if enable then
vim.fn.mkdir(vim.fn.fnamemodify(M.path, ':p'), 'p')
_G.loadfile = loadfile_cached
-- add Lua loader
table.insert(loaders, 2, loader_cached)
-- add libs loader
table.insert(loaders, 3, loader_lib_cached)
-- remove Nvim loader
for l, loader in ipairs(loaders) do
if loader == vim._load_package then
table.remove(loaders, l)
break
end
end
else
_G.loadfile = _loadfile
for l, loader in ipairs(loaders) do
if loader == loader_cached or loader == loader_lib_cached then
table.remove(loaders, l)
end
end
table.insert(loaders, 2, vim._load_package)
end
table.insert(loaders, 2, vim._load_package)
end
--- @deprecated
function M.disable()
vim.deprecate('vim.loader.disable', 'vim.loader.enable(false)', '0.12')
vim.loader.enable(false)
end
--- Tracks the time spent in a function

View File

@ -3,6 +3,7 @@ local validate = vim.validate
local lsp = vim._defer_require('vim.lsp', {
_changetracking = ..., --- @module 'vim.lsp._changetracking'
_folding_range = ..., --- @module 'vim.lsp._folding_range'
_snippet_grammar = ..., --- @module 'vim.lsp._snippet_grammar'
_tagfunc = ..., --- @module 'vim.lsp._tagfunc'
_watchfiles = ..., --- @module 'vim.lsp._watchfiles'
@ -57,6 +58,7 @@ lsp._request_name_to_capability = {
[ms.textDocument_documentHighlight] = { 'documentHighlightProvider' },
[ms.textDocument_documentLink] = { 'documentLinkProvider' },
[ms.textDocument_documentSymbol] = { 'documentSymbolProvider' },
[ms.textDocument_foldingRange] = { 'foldingRangeProvider' },
[ms.textDocument_formatting] = { 'documentFormattingProvider' },
[ms.textDocument_hover] = { 'hoverProvider' },
[ms.textDocument_implementation] = { 'implementationProvider' },
@ -87,18 +89,6 @@ lsp._request_name_to_capability = {
-- TODO improve handling of scratch buffers with LSP attached.
--- Returns the buffer number for the given {bufnr}.
---
---@param bufnr (integer|nil) Buffer number to resolve. Defaults to current buffer
---@return integer bufnr
local function resolve_bufnr(bufnr)
validate('bufnr', bufnr, 'number', true)
if bufnr == nil or bufnr == 0 then
return api.nvim_get_current_buf()
end
return bufnr
end
---@private
--- Called by the client when trying to call a method that's not
--- supported in any of the servers registered for the current buffer.
@ -112,6 +102,22 @@ function lsp._unsupported_method(method)
return msg
end
---@private
---@param workspace_folders string|lsp.WorkspaceFolder[]?
---@return lsp.WorkspaceFolder[]?
function lsp._get_workspace_folders(workspace_folders)
if type(workspace_folders) == 'table' then
return workspace_folders
elseif type(workspace_folders) == 'string' then
return {
{
uri = vim.uri_from_fname(workspace_folders),
name = workspace_folders,
},
}
end
end
local wait_result_reason = { [-1] = 'timeout', [-2] = 'interrupted', [-3] = 'error' }
local format_line_ending = {
@ -194,34 +200,381 @@ local function reuse_client_default(client, config)
return false
end
if config.root_dir then
local root = vim.uri_from_fname(config.root_dir)
for _, dir in ipairs(client.workspace_folders or {}) do
-- note: do not need to check client.root_dir since that should be client.workspace_folders[1]
if root == dir.uri then
return true
local config_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir)
if not config_folders or not next(config_folders) then
-- Reuse if the client was configured with no workspace folders
local client_config_folders =
lsp._get_workspace_folders(client.config.workspace_folders or client.config.root_dir)
return not client_config_folders or not next(client_config_folders)
end
for _, config_folder in ipairs(config_folders) do
local found = false
for _, client_folder in ipairs(client.workspace_folders) do
if config_folder.uri == client_folder.uri then
found = true
break
end
end
if not found then
return false
end
end
-- TODO(lewis6991): also check config.workspace_folders
return true
end
return false
--- Reset defaults set by `set_defaults`.
--- Must only be called if the last client attached to a buffer exits.
local function reset_defaults(bufnr)
if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
vim.bo[bufnr].tagfunc = nil
end
if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
vim.bo[bufnr].omnifunc = nil
end
if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
vim.bo[bufnr].formatexpr = nil
end
vim._with({ buf = bufnr }, function()
local keymap = vim.fn.maparg('K', 'n', false, true)
if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
vim.keymap.del('n', 'K', { buffer = bufnr })
end
end)
end
--- @param code integer
--- @param signal integer
--- @param client_id integer
local function on_client_exit(code, signal, client_id)
local client = all_clients[client_id]
vim.schedule(function()
for bufnr in pairs(client.attached_buffers) do
if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
api.nvim_exec_autocmds('LspDetach', {
buffer = bufnr,
modeline = false,
data = { client_id = client_id },
})
end
client.attached_buffers[bufnr] = nil
if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
reset_defaults(bufnr)
end
end
local namespace = vim.lsp.diagnostic.get_namespace(client_id)
vim.diagnostic.reset(namespace)
end)
local name = client.name or 'unknown'
-- Schedule the deletion of the client object so that it exists in the execution of LspDetach
-- autocommands
vim.schedule(function()
all_clients[client_id] = nil
-- Client can be absent if executable starts, but initialize fails
-- init/attach won't have happened
if client then
changetracking.reset(client)
end
if code ~= 0 or (signal ~= 0 and signal ~= 15) then
local msg = string.format(
'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
name,
code,
signal,
lsp.get_log_path()
)
vim.notify(msg, vim.log.levels.WARN)
end
end)
end
--- Creates and initializes a client with the given configuration.
--- @param config vim.lsp.ClientConfig Configuration for the server.
--- @return integer? client_id |vim.lsp.get_client_by_id()| Note: client may not be
--- fully initialized. Use `on_init` to do any actions once
--- the client has been initialized.
--- @return string? # Error message, if any
local function create_and_initialize_client(config)
local ok, res = pcall(require('vim.lsp.client').create, config)
if not ok then
return nil, res --[[@as string]]
end
local client = assert(res)
--- @diagnostic disable-next-line: invisible
table.insert(client._on_exit_cbs, on_client_exit)
all_clients[client.id] = client
client:initialize()
return client.id, nil
end
--- @class vim.lsp.Config : vim.lsp.ClientConfig
---
--- See `cmd` in [vim.lsp.ClientConfig].
--- @field cmd? string[]|fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient
---
--- Filetypes the client will attach to, if activated by `vim.lsp.enable()`.
--- If not provided, then the client will attach to all filetypes.
--- @field filetypes? string[]
---
--- Directory markers (.e.g. '.git/') where the LSP server will base its workspaceFolders,
--- rootUri, and rootPath on initialization. Unused if `root_dir` is provided.
--- @field root_markers? string[]
---
--- Predicate used to decide if a client should be re-used. Used on all
--- running clients. The default implementation re-uses a client if name and
--- root_dir matches.
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
--- Update the configuration for an LSP client.
---
--- Use name '*' to set default configuration for all clients.
---
--- Can also be table-assigned to redefine the configuration for a client.
---
--- Examples:
---
--- - Add a root marker for all clients:
--- ```lua
--- vim.lsp.config('*', {
--- root_markers = { '.git' },
--- })
--- ```
--- - Add additional capabilities to all clients:
--- ```lua
--- vim.lsp.config('*', {
--- capabilities = {
--- textDocument = {
--- semanticTokens = {
--- multilineTokenSupport = true,
--- }
--- }
--- }
--- })
--- ```
--- - (Re-)define the configuration for clangd:
--- ```lua
--- vim.lsp.config.clangd = {
--- cmd = {
--- 'clangd',
--- '--clang-tidy',
--- '--background-index',
--- '--offset-encoding=utf-8',
--- },
--- root_markers = { '.clangd', 'compile_commands.json' },
--- filetypes = { 'c', 'cpp' },
--- }
--- ```
--- - Get configuration for luals:
--- ```lua
--- local cfg = vim.lsp.config.luals
--- ```
---
--- @param name string
--- @param cfg vim.lsp.Config
--- @diagnostic disable-next-line:assign-type-mismatch
function lsp.config(name, cfg)
local _, _ = name, cfg -- ignore unused
-- dummy proto for docs
end
lsp._enabled_configs = {} --- @type table<string,{resolved_config:vim.lsp.Config?}>
--- If a config in vim.lsp.config() is accessed then the resolved config becomes invalid.
--- @param name string
local function invalidate_enabled_config(name)
if name == '*' then
for _, v in pairs(lsp._enabled_configs) do
v.resolved_config = nil
end
elseif lsp._enabled_configs[name] then
lsp._enabled_configs[name].resolved_config = nil
end
end
--- @nodoc
--- @class vim.lsp.config
--- @field [string] vim.lsp.Config
--- @field package _configs table<string,vim.lsp.Config>
lsp.config = setmetatable({ _configs = {} }, {
--- @param self vim.lsp.config
--- @param name string
--- @return vim.lsp.Config
__index = function(self, name)
validate('name', name, 'string')
invalidate_enabled_config(name)
self._configs[name] = self._configs[name] or {}
return self._configs[name]
end,
--- @param self vim.lsp.config
--- @param name string
--- @param cfg vim.lsp.Config
__newindex = function(self, name, cfg)
validate('name', name, 'string')
validate('cfg', cfg, 'table')
invalidate_enabled_config(name)
self._configs[name] = cfg
end,
--- @param self vim.lsp.config
--- @param name string
--- @param cfg vim.lsp.Config
__call = function(self, name, cfg)
validate('name', name, 'string')
validate('cfg', cfg, 'table')
invalidate_enabled_config(name)
self[name] = vim.tbl_deep_extend('force', self._configs[name] or {}, cfg)
end,
})
--- @private
--- @param name string
--- @return vim.lsp.Config
function lsp._resolve_config(name)
local econfig = lsp._enabled_configs[name] or {}
if not econfig.resolved_config then
-- Resolve configs from lsp/*.lua
-- Calls to vim.lsp.config in lsp/* have a lower precedence than calls from other sites.
local orig_configs = lsp.config._configs
lsp.config._configs = {}
pcall(vim.cmd.runtime, { ('lsp/%s.lua'):format(name), bang = true })
local rtp_configs = lsp.config._configs
lsp.config._configs = orig_configs
local config = vim.tbl_deep_extend(
'force',
lsp.config._configs['*'] or {},
rtp_configs[name] or {},
lsp.config._configs[name] or {}
)
config.name = name
validate('cmd', config.cmd, { 'function', 'table' })
validate('cmd', config.reuse_client, 'function', true)
-- All other fields are validated in client.create
econfig.resolved_config = config
end
return assert(econfig.resolved_config)
end
local lsp_enable_autocmd_id --- @type integer?
--- @param bufnr integer
local function lsp_enable_callback(bufnr)
-- Only ever attach to buffers that represent an actual file.
if vim.bo[bufnr].buftype ~= '' then
return
end
--- @param config vim.lsp.Config
local function can_start(config)
if config.filetypes and not vim.tbl_contains(config.filetypes, vim.bo[bufnr].filetype) then
return false
elseif type(config.cmd) == 'table' and vim.fn.executable(config.cmd[1]) == 0 then
return false
end
return true
end
for name in vim.spairs(lsp._enabled_configs) do
local config = lsp._resolve_config(name)
if can_start(config) then
-- Deepcopy config so changes done in the client
-- do not propagate back to the enabled configs.
config = vim.deepcopy(config)
vim.lsp.start(config, {
bufnr = bufnr,
reuse_client = config.reuse_client,
_root_markers = config.root_markers,
})
end
end
end
--- Enable an LSP server to automatically start when opening a buffer.
---
--- Uses configuration defined with `vim.lsp.config`.
---
--- Examples:
---
--- ```lua
--- vim.lsp.enable('clangd')
---
--- vim.lsp.enable({'luals', 'pyright'})
--- ```
---
--- @param name string|string[] Name(s) of client(s) to enable.
--- @param enable? boolean `true|nil` to enable, `false` to disable.
function lsp.enable(name, enable)
validate('name', name, { 'string', 'table' })
local names = vim._ensure_list(name) --[[@as string[] ]]
for _, nm in ipairs(names) do
if nm == '*' then
error('Invalid name')
end
lsp._enabled_configs[nm] = enable == false and nil or {}
end
if not next(lsp._enabled_configs) then
if lsp_enable_autocmd_id then
api.nvim_del_autocmd(lsp_enable_autocmd_id)
lsp_enable_autocmd_id = nil
end
return
end
-- Only ever create autocmd once to reuse computation of config merging.
lsp_enable_autocmd_id = lsp_enable_autocmd_id
or api.nvim_create_autocmd('FileType', {
group = api.nvim_create_augroup('nvim.lsp.enable', {}),
callback = function(args)
lsp_enable_callback(args.buf)
end,
})
end
--- @class vim.lsp.start.Opts
--- @inlinedoc
---
--- Predicate used to decide if a client should be re-used. Used on all
--- running clients. The default implementation re-uses a client if name and
--- root_dir matches.
--- running clients. The default implementation re-uses a client if it has the
--- same name and if the given workspace folders (or root_dir) are all included
--- in the client's workspace folders.
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
---
--- Buffer handle to attach to if starting or re-using a client (0 for current).
--- @field bufnr? integer
---
--- Whether to attach the client to a buffer (default true).
--- If set to `false`, `reuse_client` and `bufnr` will be ignored.
--- @field attach? boolean
---
--- Suppress error reporting if the LSP server fails to start (default false).
--- @field silent? boolean
---
--- @field package _root_markers? string[]
--- Create a new LSP client and start a language server or reuses an already
--- running client if one is found matching `name` and `root_dir`.
@ -237,10 +590,10 @@ end
--- })
--- ```
---
--- See |vim.lsp.start_client()| for all available options. The most important are:
--- See |vim.lsp.ClientConfig| for all available options. The most important are:
---
--- - `name` arbitrary name for the LSP client. Should be unique per language server.
--- - `cmd` command string[] or function, described at |vim.lsp.start_client()|.
--- - `cmd` command string[] or function.
--- - `root_dir` path to the project root. By default this is used to decide if an existing client
--- should be re-used. The example above uses |vim.fs.root()| to detect the root by traversing
--- the file system upwards starting from the current directory until either a `pyproject.toml`
@ -260,36 +613,46 @@ end
--- `ftplugin/<filetype_name>.lua` (See |ftplugin-name|)
---
--- @param config vim.lsp.ClientConfig Configuration for the server.
--- @param opts vim.lsp.start.Opts? Optional keyword arguments
--- @param opts vim.lsp.start.Opts? Optional keyword arguments.
--- @return integer? client_id
function lsp.start(config, opts)
opts = opts or {}
local reuse_client = opts.reuse_client or reuse_client_default
local bufnr = resolve_bufnr(opts.bufnr)
local bufnr = vim._resolve_bufnr(opts.bufnr)
if not config.root_dir and opts._root_markers then
config = vim.deepcopy(config)
config.root_dir = vim.fs.root(bufnr, opts._root_markers)
end
for _, client in pairs(all_clients) do
if reuse_client(client, config) then
if opts.attach == false then
return client.id
end
if lsp.buf_attach_client(bufnr, client.id) then
return client.id
else
return nil
end
return
end
end
local client_id, err = lsp.start_client(config)
local client_id, err = create_and_initialize_client(config)
if err then
if not opts.silent then
vim.notify(err, vim.log.levels.WARN)
end
return nil
return
end
if opts.attach == false then
return client_id
end
if client_id and lsp.buf_attach_client(bufnr, client_id) then
return client_id
end
return nil
end
--- Consumes the latest progress messages from all clients and formats them as a string.
@ -381,78 +744,7 @@ function lsp._set_defaults(client, bufnr)
end
end
--- Reset defaults set by `set_defaults`.
--- Must only be called if the last client attached to a buffer exits.
local function reset_defaults(bufnr)
if vim.bo[bufnr].tagfunc == 'v:lua.vim.lsp.tagfunc' then
vim.bo[bufnr].tagfunc = nil
end
if vim.bo[bufnr].omnifunc == 'v:lua.vim.lsp.omnifunc' then
vim.bo[bufnr].omnifunc = nil
end
if vim.bo[bufnr].formatexpr == 'v:lua.vim.lsp.formatexpr()' then
vim.bo[bufnr].formatexpr = nil
end
vim._with({ buf = bufnr }, function()
local keymap = vim.fn.maparg('K', 'n', false, true)
if keymap and keymap.callback == vim.lsp.buf.hover and keymap.buffer == 1 then
vim.keymap.del('n', 'K', { buffer = bufnr })
end
end)
end
--- @param code integer
--- @param signal integer
--- @param client_id integer
local function on_client_exit(code, signal, client_id)
local client = all_clients[client_id]
vim.schedule(function()
for bufnr in pairs(client.attached_buffers) do
if client and client.attached_buffers[bufnr] and api.nvim_buf_is_valid(bufnr) then
api.nvim_exec_autocmds('LspDetach', {
buffer = bufnr,
modeline = false,
data = { client_id = client_id },
})
end
client.attached_buffers[bufnr] = nil
if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then
reset_defaults(bufnr)
end
end
local namespace = vim.lsp.diagnostic.get_namespace(client_id)
vim.diagnostic.reset(namespace)
end)
local name = client.name or 'unknown'
-- Schedule the deletion of the client object so that it exists in the execution of LspDetach
-- autocommands
vim.schedule(function()
all_clients[client_id] = nil
-- Client can be absent if executable starts, but initialize fails
-- init/attach won't have happened
if client then
changetracking.reset(client)
end
if code ~= 0 or (signal ~= 0 and signal ~= 15) then
local msg = string.format(
'Client %s quit with exit code %s and signal %s. Check log for errors: %s',
name,
code,
signal,
lsp.get_log_path()
)
vim.notify(msg, vim.log.levels.WARN)
end
end)
end
--- @deprecated
--- Starts and initializes a client with the given configuration.
--- @param config vim.lsp.ClientConfig Configuration for the server.
--- @return integer? client_id |vim.lsp.get_client_by_id()| Note: client may not be
@ -460,27 +752,14 @@ end
--- the client has been initialized.
--- @return string? # Error message, if any
function lsp.start_client(config)
local ok, res = pcall(require('vim.lsp.client').create, config)
if not ok then
return nil, res --[[@as string]]
end
local client = assert(res)
--- @diagnostic disable-next-line: invisible
table.insert(client._on_exit_cbs, on_client_exit)
all_clients[client.id] = client
client:initialize()
return client.id, nil
vim.deprecate('vim.lsp.start_client()', 'vim.lsp.start()', '0.13')
return create_and_initialize_client(config)
end
---Buffer lifecycle handler for textDocument/didSave
--- @param bufnr integer
local function text_document_did_save_handler(bufnr)
bufnr = resolve_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
local uri = vim.uri_from_bufnr(bufnr)
local text = once(lsp._buf_get_full_text)
for _, client in ipairs(lsp.get_clients({ bufnr = bufnr })) do
@ -641,7 +920,7 @@ end
function lsp.buf_attach_client(bufnr, client_id)
validate('bufnr', bufnr, 'number', true)
validate('client_id', client_id, 'number')
bufnr = resolve_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
if not api.nvim_buf_is_loaded(bufnr) then
log.warn(string.format('buf_attach_client called on unloaded buffer (id: %d): ', bufnr))
return false
@ -678,7 +957,7 @@ end
function lsp.buf_detach_client(bufnr, client_id)
validate('bufnr', bufnr, 'number', true)
validate('client_id', client_id, 'number')
bufnr = resolve_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
local client = all_clients[client_id]
if not client or not client.attached_buffers[bufnr] then
@ -784,7 +1063,7 @@ function lsp.get_clients(filter)
local clients = {} --- @type vim.lsp.Client[]
local bufnr = filter.bufnr and resolve_bufnr(filter.bufnr)
local bufnr = filter.bufnr and vim._resolve_bufnr(filter.bufnr)
for _, client in pairs(all_clients) do
if
@ -880,7 +1159,7 @@ function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
validate('handler', handler, 'function', true)
validate('on_unsupported', on_unsupported, 'function', true)
bufnr = resolve_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
local method_supported = false
local clients = lsp.get_clients({ bufnr = bufnr })
local client_request_ids = {} --- @type table<integer,integer>
@ -1094,6 +1373,54 @@ function lsp.tagfunc(pattern, flags)
return vim.lsp._tagfunc(pattern, flags)
end
--- Provides an interface between the built-in client and a `foldexpr` function.
---
--- To use, check for the "textDocument/foldingRange" capability in an
--- |LspAttach| autocommand. Example:
---
--- ```lua
--- vim.api.nvim_create_autocommand('LspAttach', {
--- callback = function(args)
--- local client = vim.lsp.get_client_by_id(args.data.client_id)
--- if client:supports_method('textDocument/foldingRange') then
--- vim.wo.foldmethod = 'expr'
--- vim.wo.foldexpr = 'v:lua.vim.lsp.foldexpr()'
--- end
--- end,
--- })
--- ```
---
---@param lnum integer line number
function lsp.foldexpr(lnum)
return vim.lsp._folding_range.foldexpr(lnum)
end
--- Close all {kind} of folds in the the window with {winid}.
---
--- To automatically fold imports when opening a file, you can use an autocmd:
---
--- ```lua
--- vim.api.nvim_create_autocmd('LspNotify', {
--- callback = function(args)
--- if args.data.method == 'textDocument/didOpen' then
--- vim.lsp.foldclose('imports', vim.fn.bufwinid(args.buf))
--- end
--- end,
--- })
--- ```
---
---@param kind lsp.FoldingRangeKind Kind to close, one of "comment", "imports" or "region".
---@param winid? integer Defaults to the current window.
function lsp.foldclose(kind, winid)
return vim.lsp._folding_range.foldclose(kind, winid)
end
--- Provides a `foldtext` function that shows the `collapsedText` retrieved,
--- defaults to the first folded line if `collapsedText` is not provided.
function lsp.foldtext()
return vim.lsp._folding_range.foldtext()
end
---Checks whether a client is stopped.
---
---@param client_id (integer)
@ -1112,7 +1439,7 @@ end
function lsp.buf_get_clients(bufnr)
vim.deprecate('vim.lsp.buf_get_clients()', 'vim.lsp.get_clients()', '0.12')
local result = {} --- @type table<integer,vim.lsp.Client>
for _, client in ipairs(lsp.get_clients({ bufnr = resolve_bufnr(bufnr) })) do
for _, client in ipairs(lsp.get_clients({ bufnr = vim._resolve_bufnr(bufnr) })) do
result[client.id] = client
end
return result
@ -1166,7 +1493,7 @@ function lsp.for_each_buffer_client(bufnr, fn)
'lsp.get_clients({ bufnr = bufnr }) with regular loop',
'0.12'
)
bufnr = resolve_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
for _, client in pairs(lsp.get_clients({ bufnr = bufnr })) do
fn(client, client.id, bufnr)
@ -1183,44 +1510,6 @@ function lsp.with(handler, override_config)
end
end
--- Helper function to use when implementing a handler.
--- This will check that all of the keys in the user configuration
--- are valid keys and make sense to include for this handler.
---
--- Will error on invalid keys (i.e. keys that do not exist in the options)
--- @param name string
--- @param options table<string,any>
--- @param user_config table<string,any>
function lsp._with_extend(name, options, user_config)
user_config = user_config or {}
local resulting_config = {} --- @type table<string,any>
for k, v in pairs(user_config) do
if options[k] == nil then
error(
debug.traceback(
string.format(
'Invalid option for `%s`: %s. Valid options are:\n%s',
name,
k,
vim.inspect(vim.tbl_keys(options))
)
)
)
end
resulting_config[k] = v
end
for k, v in pairs(options) do
if resulting_config[k] == nil then
resulting_config[k] = v
end
end
return resulting_config
end
--- Registry for client side commands.
--- This is an extension point for plugins to handle custom commands which are
--- not part of the core language server protocol specification.
@ -1229,7 +1518,7 @@ end
--- and the value is a function which is called if any LSP action
--- (code action, code lenses, ...) triggers the command.
---
--- If a LSP response contains a command for which no matching entry is
--- If an LSP response contains a command for which no matching entry is
--- available in this registry, the command will be executed via the LSP server
--- using `workspace/executeCommand`.
---

View File

@ -18,14 +18,14 @@ local M = {}
---
--- None: One group for all clients
--- Full: One group for all clients
--- Incremental: One group per `offset_encoding`
--- Incremental: One group per `position_encoding`
---
--- Sending changes can be debounced per buffer. To simplify the implementation the
--- smallest debounce interval is used and we don't group clients by different intervals.
---
--- @class vim.lsp.CTGroup
--- @field sync_kind integer TextDocumentSyncKind, considers config.flags.allow_incremental_sync
--- @field offset_encoding "utf-8"|"utf-16"|"utf-32"
--- @field position_encoding "utf-8"|"utf-16"|"utf-32"
---
--- @class vim.lsp.CTBufferState
--- @field name string name of the buffer
@ -46,7 +46,7 @@ local M = {}
---@return string
local function group_key(group)
if group.sync_kind == protocol.TextDocumentSyncKind.Incremental then
return tostring(group.sync_kind) .. '\0' .. group.offset_encoding
return tostring(group.sync_kind) .. '\0' .. group.position_encoding
end
return tostring(group.sync_kind)
end
@ -72,7 +72,7 @@ local function get_group(client)
end
return {
sync_kind = sync_kind,
offset_encoding = client.offset_encoding,
position_encoding = client.offset_encoding,
}
end
@ -310,7 +310,7 @@ local function send_changes_for_group(bufnr, firstline, lastline, new_lastline,
-- The contents would further change and startline/endline may no longer fit
local changes = incremental_changes(
buf_state,
group.offset_encoding,
group.position_encoding,
bufnr,
firstline,
lastline,

View File

@ -0,0 +1,373 @@
local util = require('vim.lsp.util')
local log = require('vim.lsp.log')
local ms = require('vim.lsp.protocol').Methods
local api = vim.api
local M = {}
---@class (private) vim.lsp.folding_range.BufState
---
---@field version? integer
---
--- Never use this directly, `renew()` the cached foldinfo
--- then use on demand via `row_*` fields.
---
--- Index In the form of client_id -> ranges
---@field client_ranges table<integer, lsp.FoldingRange[]?>
---
--- Index in the form of row -> [foldlevel, mark]
---@field row_level table<integer, [integer, ">" | "<"?]?>
---
--- Index in the form of start_row -> kinds
---@field row_kinds table<integer, table<lsp.FoldingRangeKind, true?>?>>
---
--- Index in the form of start_row -> collapsed_text
---@field row_text table<integer, string?>
---@type table<integer, vim.lsp.folding_range.BufState?>
local bufstates = {}
--- Renew the cached foldinfo in the buffer.
---@param bufnr integer
local function renew(bufnr)
local bufstate = assert(bufstates[bufnr])
---@type table<integer, [integer, ">" | "<"?]?>
local row_level = {}
---@type table<integer, table<lsp.FoldingRangeKind, true?>?>>
local row_kinds = {}
---@type table<integer, string?>
local row_text = {}
for _, ranges in pairs(bufstate.client_ranges) do
for _, range in ipairs(ranges) do
local start_row = range.startLine
local end_row = range.endLine
-- Adding folds within a single line is not supported by Nvim.
if start_row ~= end_row then
row_text[start_row] = range.collapsedText
local kind = range.kind
if kind then
local kinds = row_kinds[start_row] or {}
kinds[kind] = true
row_kinds[start_row] = kinds
end
for row = start_row, end_row do
local level = row_level[row] or { 0 }
level[1] = level[1] + 1
row_level[row] = level
end
row_level[start_row][2] = '>'
row_level[end_row][2] = '<'
end
end
end
bufstate.row_level = row_level
bufstate.row_kinds = row_kinds
bufstate.row_text = row_text
end
--- Renew the cached foldinfo then force `foldexpr()` to be re-evaluated,
--- without opening folds.
---@param bufnr integer
local function foldupdate(bufnr)
renew(bufnr)
for _, winid in ipairs(vim.fn.win_findbuf(bufnr)) do
local wininfo = vim.fn.getwininfo(winid)[1]
if wininfo and wininfo.tabnr == vim.fn.tabpagenr() then
if vim.wo[winid].foldmethod == 'expr' then
vim._foldupdate(winid, 0, api.nvim_buf_line_count(bufnr))
end
end
end
end
--- Whether `foldupdate()` is scheduled for the buffer with `bufnr`.
---
--- Index in the form of bufnr -> true?
---@type table<integer, true?>
local scheduled_foldupdate = {}
--- Schedule `foldupdate()` after leaving insert mode.
---@param bufnr integer
local function schedule_foldupdate(bufnr)
if not scheduled_foldupdate[bufnr] then
scheduled_foldupdate[bufnr] = true
api.nvim_create_autocmd('InsertLeave', {
buffer = bufnr,
once = true,
callback = function()
foldupdate(bufnr)
scheduled_foldupdate[bufnr] = nil
end,
})
end
end
---@param results table<integer,{err: lsp.ResponseError?, result: lsp.FoldingRange[]?}>
---@type lsp.MultiHandler
local function multi_handler(results, ctx)
local bufnr = assert(ctx.bufnr)
-- Handling responses from outdated buffer only causes performance overhead.
if util.buf_versions[bufnr] ~= ctx.version then
return
end
local bufstate = assert(bufstates[bufnr])
for client_id, result in pairs(results) do
if result.err then
log.error(result.err)
else
bufstate.client_ranges[client_id] = result.result
end
end
bufstate.version = ctx.version
if api.nvim_get_mode().mode:match('^i') then
-- `foldUpdate()` is guarded in insert mode.
schedule_foldupdate(bufnr)
else
foldupdate(bufnr)
end
end
---@param result lsp.FoldingRange[]?
---@type lsp.Handler
local function handler(err, result, ctx)
multi_handler({ [ctx.client_id] = { err = err, result = result } }, ctx)
end
--- Request `textDocument/foldingRange` from the server.
--- `foldupdate()` is scheduled once after the request is completed.
---@param bufnr integer
---@param client? vim.lsp.Client The client whose server supports `foldingRange`.
local function request(bufnr, client)
---@type lsp.FoldingRangeParams
local params = { textDocument = util.make_text_document_params(bufnr) }
if client then
client:request(ms.textDocument_foldingRange, params, handler, bufnr)
return
end
if not next(vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_foldingRange })) then
return
end
vim.lsp.buf_request_all(bufnr, ms.textDocument_foldingRange, params, multi_handler)
end
-- NOTE:
-- `bufstate` and event hooks are interdependent:
-- * `bufstate` needs event hooks for correctness.
-- * event hooks require the previous `bufstate` for updates.
-- Since they are manually created and destroyed,
-- we ensure their lifecycles are always synchronized.
--
-- TODO(ofseed):
-- 1. Implement clearing `bufstate` and event hooks
-- when no clients in the buffer support the corresponding method.
-- 2. Then generalize this state management to other LSP modules.
local augroup_setup = api.nvim_create_augroup('vim_lsp_folding_range/setup', {})
--- Initialize `bufstate` and event hooks, then request folding ranges.
--- Manage their lifecycle within this function.
---@param bufnr integer
---@return vim.lsp.folding_range.BufState?
local function setup(bufnr)
if not api.nvim_buf_is_loaded(bufnr) then
return
end
-- Register the new `bufstate`.
bufstates[bufnr] = {
client_ranges = {},
row_level = {},
row_kinds = {},
row_text = {},
}
-- Event hooks from `buf_attach` can't be removed externally.
-- Hooks and `bufstate` share the same lifecycle;
-- they should self-destroy if `bufstate == nil`.
api.nvim_buf_attach(bufnr, false, {
-- `on_detach` also runs on buffer reload (`:e`).
-- Ensure `bufstate` and hooks are cleared to avoid duplication or leftover states.
on_detach = function()
bufstates[bufnr] = nil
api.nvim_clear_autocmds({ buffer = bufnr, group = augroup_setup })
end,
-- Reset `bufstate` and request folding ranges.
on_reload = function()
bufstates[bufnr] = {
client_ranges = {},
row_level = {},
row_kinds = {},
row_text = {},
}
request(bufnr)
end,
--- Sync changed rows with their previous foldlevels before applying new ones.
on_bytes = function(_, _, _, start_row, _, _, old_row, _, _, new_row, _, _)
if bufstates[bufnr] == nil then
return true
end
local row_level = bufstates[bufnr].row_level
if next(row_level) == nil then
return
end
local row = new_row - old_row
if row > 0 then
vim._list_insert(row_level, start_row, start_row + math.abs(row) - 1, { -1 })
-- If the previous row ends a fold,
-- Nvim treats the first row after consecutive `-1`s as a new fold start,
-- which is not the desired behavior.
local prev_level = row_level[start_row - 1]
if prev_level and prev_level[2] == '<' then
row_level[start_row] = { prev_level[1] - 1 }
end
elseif row < 0 then
vim._list_remove(row_level, start_row, start_row + math.abs(row) - 1)
end
end,
})
api.nvim_create_autocmd('LspDetach', {
group = augroup_setup,
buffer = bufnr,
callback = function(args)
if not api.nvim_buf_is_loaded(bufnr) then
return
end
---@type integer
local client_id = args.data.client_id
bufstates[bufnr].client_ranges[client_id] = nil
---@type vim.lsp.Client[]
local clients = vim
.iter(vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_foldingRange }))
---@param client vim.lsp.Client
:filter(function(client)
return client.id ~= client_id
end)
:totable()
if #clients == 0 then
bufstates[bufnr] = {
client_ranges = {},
row_level = {},
row_kinds = {},
row_text = {},
}
end
foldupdate(bufnr)
end,
})
api.nvim_create_autocmd('LspAttach', {
group = augroup_setup,
buffer = bufnr,
callback = function(args)
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
if client:supports_method(vim.lsp.protocol.Methods.textDocument_foldingRange, bufnr) then
request(bufnr, client)
end
end,
})
api.nvim_create_autocmd('LspNotify', {
group = augroup_setup,
buffer = bufnr,
callback = function(args)
local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
if
client:supports_method(ms.textDocument_foldingRange, bufnr)
and (
args.data.method == ms.textDocument_didChange
or args.data.method == ms.textDocument_didOpen
)
then
request(bufnr, client)
end
end,
})
request(bufnr)
return bufstates[bufnr]
end
---@param kind lsp.FoldingRangeKind
---@param winid integer
local function foldclose(kind, winid)
vim._with({ win = winid }, function()
local bufnr = api.nvim_win_get_buf(winid)
local row_kinds = bufstates[bufnr].row_kinds
-- Reverse traverse to ensure that the smallest ranges are closed first.
for row = api.nvim_buf_line_count(bufnr) - 1, 0, -1 do
local kinds = row_kinds[row]
if kinds and kinds[kind] then
vim.cmd(row + 1 .. 'foldclose')
end
end
end)
end
---@param kind lsp.FoldingRangeKind
---@param winid? integer
function M.foldclose(kind, winid)
vim.validate('kind', kind, 'string')
vim.validate('winid', winid, 'number', true)
winid = winid or api.nvim_get_current_win()
local bufnr = api.nvim_win_get_buf(winid)
local bufstate = bufstates[bufnr]
if not bufstate then
return
end
if bufstate.version == util.buf_versions[bufnr] then
foldclose(kind, winid)
return
end
-- Schedule `foldclose()` if the buffer is not up-to-date.
if not next(vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_foldingRange })) then
return
end
---@type lsp.FoldingRangeParams
local params = { textDocument = util.make_text_document_params(bufnr) }
vim.lsp.buf_request_all(bufnr, ms.textDocument_foldingRange, params, function(...)
multi_handler(...)
foldclose(kind, winid)
end)
end
---@return string
function M.foldtext()
local bufnr = api.nvim_get_current_buf()
local lnum = vim.v.foldstart
local row = lnum - 1
local bufstate = bufstates[bufnr]
if bufstate and bufstate.row_text[row] then
return bufstate.row_text[row]
end
return vim.fn.getline(lnum)
end
---@param lnum? integer
---@return string level
function M.foldexpr(lnum)
local bufnr = api.nvim_get_current_buf()
local bufstate = bufstates[bufnr] or setup(bufnr)
if not bufstate then
return '0'
end
local row = (lnum or vim.v.lnum) - 1
local level = bufstate.row_level[row]
return level and (level[2] or '') .. (level[1] or '0') or '0'
end
return M

View File

@ -6,12 +6,12 @@ local ms = lsp.protocol.Methods
---@param name string
---@param range lsp.Range
---@param uri string
---@param offset_encoding string
---@param position_encoding string
---@return {name: string, filename: string, cmd: string, kind?: string}
local function mk_tag_item(name, range, uri, offset_encoding)
local function mk_tag_item(name, range, uri, position_encoding)
local bufnr = vim.uri_to_bufnr(uri)
-- This is get_line_byte_from_position is 0-indexed, call cursor expects a 1-indexed position
local byte = util._get_line_byte_from_position(bufnr, range.start, offset_encoding) + 1
local byte = util._get_line_byte_from_position(bufnr, range.start, position_encoding) + 1
return {
name = name,
filename = vim.uri_to_fname(uri),
@ -32,9 +32,9 @@ local function query_definition(pattern)
--- @param range lsp.Range
--- @param uri string
--- @param offset_encoding string
local add = function(range, uri, offset_encoding)
table.insert(results, mk_tag_item(pattern, range, uri, offset_encoding))
--- @param position_encoding string
local add = function(range, uri, position_encoding)
table.insert(results, mk_tag_item(pattern, range, uri, position_encoding))
end
local remaining = #clients
@ -78,11 +78,11 @@ local function query_workspace_symbols(pattern)
local results = {}
for client_id, responses in pairs(assert(results_by_client)) do
local client = lsp.get_client_by_id(client_id)
local offset_encoding = client and client.offset_encoding or 'utf-16'
local position_encoding = client and client.offset_encoding or 'utf-16'
local symbols = responses.result --[[@as lsp.SymbolInformation[]|nil]]
for _, symbol in pairs(symbols or {}) do
local loc = symbol.location
local item = mk_tag_item(symbol.name, loc.range, loc.uri, offset_encoding)
local item = mk_tag_item(symbol.name, loc.range, loc.uri, position_encoding)
item.kind = lsp.protocol.SymbolKind[symbol.kind] or 'Unknown'
table.insert(results, item)
end

View File

@ -0,0 +1,182 @@
local uv = vim.uv
local log = require('vim.lsp.log')
local is_win = vim.fn.has('win32') == 1
--- Checks whether a given path exists and is a directory.
---@param filename string path to check
---@return boolean
local function is_dir(filename)
local stat = uv.fs_stat(filename)
return stat and stat.type == 'directory' or false
end
--- @class (private) vim.lsp.rpc.Transport
--- @field write fun(self: vim.lsp.rpc.Transport, msg: string)
--- @field is_closing fun(self: vim.lsp.rpc.Transport): boolean
--- @field terminate fun(self: vim.lsp.rpc.Transport)
--- @class (private,exact) vim.lsp.rpc.Transport.Run : vim.lsp.rpc.Transport
--- @field new fun(): vim.lsp.rpc.Transport.Run
--- @field sysobj? vim.SystemObj
local TransportRun = {}
--- @return vim.lsp.rpc.Transport.Run
function TransportRun.new()
return setmetatable({}, { __index = TransportRun })
end
--- @param cmd string[] Command to start the LSP server.
--- @param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams
--- @param on_read fun(err: any, data: string)
--- @param on_exit fun(code: integer, signal: integer)
function TransportRun:run(cmd, extra_spawn_params, on_read, on_exit)
local function on_stderr(_, chunk)
if chunk then
log.error('rpc', cmd[1], 'stderr', chunk)
end
end
extra_spawn_params = extra_spawn_params or {}
if extra_spawn_params.cwd then
assert(is_dir(extra_spawn_params.cwd), 'cwd must be a directory')
end
local detached = not is_win
if extra_spawn_params.detached ~= nil then
detached = extra_spawn_params.detached
end
local ok, sysobj_or_err = pcall(vim.system, cmd, {
stdin = true,
stdout = on_read,
stderr = on_stderr,
cwd = extra_spawn_params.cwd,
env = extra_spawn_params.env,
detach = detached,
}, function(obj)
on_exit(obj.code, obj.signal)
end)
if not ok then
local err = sysobj_or_err --[[@as string]]
local sfx = err:match('ENOENT')
and '. The language server is either not installed, missing from PATH, or not executable.'
or string.format(' with error message: %s', err)
error(('Spawning language server with cmd: `%s` failed%s'):format(vim.inspect(cmd), sfx))
end
self.sysobj = sysobj_or_err --[[@as vim.SystemObj]]
end
function TransportRun:write(msg)
assert(self.sysobj):write(msg)
end
function TransportRun:is_closing()
return self.sysobj == nil or self.sysobj:is_closing()
end
function TransportRun:terminate()
assert(self.sysobj):kill(15)
end
--- @class (private,exact) vim.lsp.rpc.Transport.Connect : vim.lsp.rpc.Transport
--- @field new fun(): vim.lsp.rpc.Transport.Connect
--- @field handle? uv.uv_pipe_t|uv.uv_tcp_t
--- Connect returns a PublicClient synchronously so the caller
--- can immediately send messages before the connection is established
--- -> Need to buffer them until that happens
--- @field connected boolean
--- @field closing boolean
--- @field msgbuf vim.Ringbuf
--- @field on_exit? fun(code: integer, signal: integer)
local TransportConnect = {}
--- @return vim.lsp.rpc.Transport.Connect
function TransportConnect.new()
return setmetatable({
connected = false,
-- size should be enough because the client can't really do anything until initialization is done
-- which required a response from the server - implying the connection got established
msgbuf = vim.ringbuf(10),
closing = false,
}, { __index = TransportConnect })
end
--- @param host_or_path string
--- @param port? integer
--- @param on_read fun(err: any, data: string)
--- @param on_exit? fun(code: integer, signal: integer)
function TransportConnect:connect(host_or_path, port, on_read, on_exit)
self.on_exit = on_exit
self.handle = (
port and assert(uv.new_tcp(), 'Could not create new TCP socket')
or assert(uv.new_pipe(false), 'Pipe could not be opened.')
)
local function on_connect(err)
if err then
local address = not port and host_or_path or (host_or_path .. ':' .. port)
vim.schedule(function()
vim.notify(
string.format('Could not connect to %s, reason: %s', address, vim.inspect(err)),
vim.log.levels.WARN
)
end)
return
end
self.handle:read_start(on_read)
self.connected = true
for msg in self.msgbuf do
self.handle:write(msg)
end
end
if not port then
self.handle:connect(host_or_path, on_connect)
return
end
--- @diagnostic disable-next-line:param-type-mismatch bad UV typing
local info = uv.getaddrinfo(host_or_path, nil)
local resolved_host = info and info[1] and info[1].addr or host_or_path
self.handle:connect(resolved_host, port, on_connect)
end
function TransportConnect:write(msg)
if self.connected then
local _, err = self.handle:write(msg)
if err and not self.closing then
log.error('Error on handle:write: %q', err)
end
return
end
self.msgbuf:push(msg)
end
function TransportConnect:is_closing()
return self.closing
end
function TransportConnect:terminate()
if self.closing then
return
end
self.closing = true
if self.handle then
self.handle:shutdown()
self.handle:close()
end
if self.on_exit then
self.on_exit(0, 0)
end
end
return {
TransportRun = TransportRun,
TransportConnect = TransportConnect,
}

View File

@ -487,7 +487,7 @@ end
--- ```lua
--- -- Never request typescript-language-server for formatting
--- vim.lsp.buf.format {
--- filter = function(client) return client.name ~= "tsserver" end
--- filter = function(client) return client.name ~= "ts_ls" end
--- }
--- ```
--- @field filter? fun(client: vim.lsp.Client): boolean?
@ -519,7 +519,7 @@ end
--- @param opts? vim.lsp.buf.format.Opts
function M.format(opts)
opts = opts or {}
local bufnr = opts.bufnr or api.nvim_get_current_buf()
local bufnr = vim._resolve_bufnr(opts.bufnr)
local mode = api.nvim_get_mode().mode
local range = opts.range
-- Try to use visual selection if no range is given
@ -617,7 +617,7 @@ end
---@param opts? vim.lsp.buf.rename.Opts Additional options:
function M.rename(new_name, opts)
opts = opts or {}
local bufnr = opts.bufnr or api.nvim_get_current_buf()
local bufnr = vim._resolve_bufnr(opts.bufnr)
local clients = lsp.get_clients({
bufnr = bufnr,
name = opts.name,
@ -638,14 +638,14 @@ function M.rename(new_name, opts)
local cword = vim.fn.expand('<cword>')
--- @param range lsp.Range
--- @param offset_encoding string
local function get_text_at_range(range, offset_encoding)
--- @param position_encoding string
local function get_text_at_range(range, position_encoding)
return api.nvim_buf_get_text(
bufnr,
range.start.line,
util._get_line_byte_from_position(bufnr, range.start, offset_encoding),
util._get_line_byte_from_position(bufnr, range.start, position_encoding),
range['end'].line,
util._get_line_byte_from_position(bufnr, range['end'], offset_encoding),
util._get_line_byte_from_position(bufnr, range['end'], position_encoding),
{}
)[1]
end
@ -736,7 +736,7 @@ end
--- Lists all the references to the symbol under the cursor in the quickfix window.
---
---@param context (table|nil) Context for the request
---@param context lsp.ReferenceContext? Context for the request
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
---@param opts? vim.lsp.ListOpts
function M.references(context, opts)

View File

@ -75,17 +75,17 @@ local validate = vim.validate
---
--- Map with language server specific settings.
--- See the {settings} in |vim.lsp.Client|.
--- @field settings? table
--- @field settings? lsp.LSPObject
---
--- Table that maps string of clientside commands to user-defined functions.
--- Commands passed to start_client take precedence over the global command registry. Each key
--- Commands passed to `start()` take precedence over the global command registry. Each key
--- must be a unique command name, and the value is a function which is called if any LSP action
--- (code action, code lenses, ...) triggers the command.
--- @field commands? table<string,fun(command: lsp.Command, ctx: table)>
---
--- Values to pass in the initialization request as `initializationOptions`. See `initialize` in
--- the LSP spec.
--- @field init_options? table
--- @field init_options? lsp.LSPObject
---
--- Name in log messages.
--- (default: client-id)
@ -94,7 +94,8 @@ local validate = vim.validate
--- Language ID as string. Defaults to the buffer filetype.
--- @field get_language_id? fun(bufnr: integer, filetype: string): string
---
--- The encoding that the LSP server expects. Client does not verify this is correct.
--- Called "position encoding" in LSP spec, the encoding that the LSP server expects.
--- Client does not verify this is correct.
--- @field offset_encoding? 'utf-8'|'utf-16'|'utf-32'
---
--- Callback invoked when the client operation throws an error. `code` is a number describing the error.
@ -103,7 +104,7 @@ local validate = vim.validate
--- @field on_error? fun(code: integer, err: string)
---
--- Callback invoked before the LSP "initialize" phase, where `params` contains the parameters
--- being sent to the server and `config` is the config that was passed to |vim.lsp.start_client()|.
--- being sent to the server and `config` is the config that was passed to |vim.lsp.start()|.
--- You can use this to modify parameters before they are sent.
--- @field before_init? fun(params: lsp.InitializeParams, config: vim.lsp.ClientConfig)
---
@ -148,8 +149,10 @@ local validate = vim.validate
--- See |vim.lsp.rpc.start()|.
--- @field rpc vim.lsp.rpc.PublicClient
---
--- The encoding used for communicating with the server. You can modify this in
--- the `config`'s `on_init` method before text is sent to the server.
--- Called "position encoding" in LSP spec,
--- the encoding used for communicating with the server.
--- You can modify this in the `config`'s `on_init` method
--- before text is sent to the server.
--- @field offset_encoding string
---
--- The handlers used by the client as described in |lsp-handler|.
@ -161,10 +164,10 @@ local validate = vim.validate
--- for an active request, or "cancel" for a cancel request. It will be
--- "complete" ephemerally while executing |LspRequest| autocmds when replies
--- are received from the server.
--- @field requests table<integer,{ type: string, bufnr: integer, method: string}>
--- @field requests table<integer,{ type: string, bufnr: integer, method: string}?>
---
--- copy of the table that was passed by the user
--- to |vim.lsp.start_client()|.
--- to |vim.lsp.start()|.
--- @field config vim.lsp.ClientConfig
---
--- Response from the server sent on `initialize` describing the server's
@ -186,9 +189,6 @@ local validate = vim.validate
---
--- @field attached_buffers table<integer,true>
---
--- Buffers that should be attached to upon initialize()
--- @field package _buffers_to_attach table<integer,true>
---
--- @field private _log_prefix string
---
--- Track this so that we can escalate automatically if we've already tried a
@ -207,7 +207,7 @@ local validate = vim.validate
--- Map with language server specific settings. These are returned to the
--- language server if requested via `workspace/configuration`. Keys are
--- case-sensitive.
--- @field settings table
--- @field settings lsp.LSPObject
---
--- A table with flags for the client. The current (experimental) flags are:
--- @field flags vim.lsp.Client.Flags
@ -262,9 +262,6 @@ local valid_encodings = {
['utf8'] = 'utf-8',
['utf16'] = 'utf-16',
['utf32'] = 'utf-32',
UTF8 = 'utf-8',
UTF16 = 'utf-16',
UTF32 = 'utf-32',
}
--- Normalizes {encoding} to valid LSP encoding names.
@ -273,12 +270,12 @@ local valid_encodings = {
local function validate_encoding(encoding)
validate('encoding', encoding, 'string', true)
if not encoding then
return valid_encodings.UTF16
return valid_encodings.utf16
end
return valid_encodings[encoding:lower()]
or error(
string.format(
"Invalid offset encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'",
"Invalid position encoding %q. Must be one of: 'utf-8', 'utf-16', 'utf-32'",
encoding
)
)
@ -304,7 +301,7 @@ local function default_get_language_id(_bufnr, filetype)
return filetype
end
--- Validates a client configuration as given to |vim.lsp.start_client()|.
--- Validates a client configuration as given to |vim.lsp.start()|.
--- @param config vim.lsp.ClientConfig
local function validate_config(config)
validate('config', config, 'table')
@ -362,31 +359,6 @@ local function get_name(id, config)
return tostring(id)
end
--- @param workspace_folders string|lsp.WorkspaceFolder[]?
--- @return lsp.WorkspaceFolder[]?
local function get_workspace_folders(workspace_folders)
if type(workspace_folders) == 'table' then
return workspace_folders
elseif type(workspace_folders) == 'string' then
return {
{
uri = vim.uri_from_fname(workspace_folders),
name = workspace_folders,
},
}
end
end
--- @generic T
--- @param x elem_or_list<T>?
--- @return T[]
local function ensure_list(x)
if type(x) == 'table' then
return x
end
return { x }
end
--- @nodoc
--- @param config vim.lsp.ClientConfig
--- @return vim.lsp.Client?
@ -413,13 +385,13 @@ function Client.create(config)
settings = config.settings or {},
flags = config.flags or {},
get_language_id = config.get_language_id or default_get_language_id,
capabilities = config.capabilities or lsp.protocol.make_client_capabilities(),
workspace_folders = get_workspace_folders(config.workspace_folders or config.root_dir),
capabilities = config.capabilities,
workspace_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir),
root_dir = config.root_dir,
_before_init_cb = config.before_init,
_on_init_cbs = ensure_list(config.on_init),
_on_exit_cbs = ensure_list(config.on_exit),
_on_attach_cbs = ensure_list(config.on_attach),
_on_init_cbs = vim._ensure_list(config.on_init),
_on_exit_cbs = vim._ensure_list(config.on_exit),
_on_attach_cbs = vim._ensure_list(config.on_attach),
_on_error_cb = config.on_error,
_trace = get_trace(config.trace),
@ -435,6 +407,9 @@ function Client.create(config)
messages = { name = name, messages = {}, progress = {}, status = {} },
}
self.capabilities =
vim.tbl_deep_extend('force', lsp.protocol.make_client_capabilities(), self.capabilities or {})
--- @class lsp.DynamicCapabilities
--- @nodoc
self.dynamic_capabilities = {
@ -616,16 +591,55 @@ function Client:_resolve_handler(method)
return self.handlers[method] or lsp.handlers[method]
end
--- Returns the buffer number for the given {bufnr}.
---
--- @param bufnr integer? Buffer number to resolve. Defaults to current buffer
--- @return integer bufnr
local function resolve_bufnr(bufnr)
validate('bufnr', bufnr, 'number', true)
if bufnr == nil or bufnr == 0 then
return api.nvim_get_current_buf()
--- @private
--- @param id integer
--- @param req_type 'pending'|'complete'|'cancel'|
--- @param bufnr? integer (only required for req_type='pending')
--- @param method? string (only required for req_type='pending')
function Client:_process_request(id, req_type, bufnr, method)
local pending = req_type == 'pending'
validate('id', id, 'number')
if pending then
validate('bufnr', bufnr, 'number')
validate('method', method, 'string')
end
return bufnr
local cur_request = self.requests[id]
if pending and cur_request then
log.error(
self._log_prefix,
('Cannot create request with id %d as one already exists'):format(id)
)
return
elseif not pending and not cur_request then
log.error(
self._log_prefix,
('Cannot find request with id %d whilst attempting to %s'):format(id, req_type)
)
return
end
if cur_request then
bufnr = cur_request.bufnr
method = cur_request.method
end
assert(bufnr and method)
local request = { type = req_type, bufnr = bufnr, method = method }
-- Clear 'complete' requests
-- Note 'pending' and 'cancelled' requests are cleared when the server sends a response
-- which is processed via the notify_reply_callback argument to rpc.request.
self.requests[id] = req_type ~= 'complete' and request or nil
api.nvim_exec_autocmds('LspRequest', {
buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
modeline = false,
data = { client_id = self.id, request_id = id, request = request },
})
end
--- Sends a request to the server.
@ -636,7 +650,7 @@ end
--- @param method string LSP method name.
--- @param params? table LSP request params.
--- @param handler? lsp.Handler Response |lsp-handler| for this method.
--- @param bufnr? integer Buffer handle. 0 for current (default).
--- @param bufnr? integer (default: 0) Buffer handle, or 0 for current.
--- @return boolean status indicates whether the request was successful.
--- If it is `false`, then it will always be `false` (the client has shutdown).
--- @return integer? request_id Can be used with |Client:cancel_request()|.
@ -652,37 +666,24 @@ function Client:request(method, params, handler, bufnr)
end
-- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state
changetracking.flush(self, bufnr)
bufnr = resolve_bufnr(bufnr)
bufnr = vim._resolve_bufnr(bufnr)
local version = lsp.util.buf_versions[bufnr]
log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr)
local success, request_id = self.rpc.request(method, params, function(err, result)
local context = {
handler(err, result, {
method = method,
client_id = self.id,
bufnr = bufnr,
params = params,
version = version,
}
handler(err, result, context)
end, function(request_id)
local request = self.requests[request_id]
request.type = 'complete'
api.nvim_exec_autocmds('LspRequest', {
buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
modeline = false,
data = { client_id = self.id, request_id = request_id, request = request },
})
self.requests[request_id] = nil
end, function(request_id)
-- Called when the server sends a response to the request (including cancelled acknowledgment).
self:_process_request(request_id, 'complete')
end)
if success and request_id then
local request = { type = 'pending', bufnr = bufnr, method = method }
self.requests[request_id] = request
api.nvim_exec_autocmds('LspRequest', {
buffer = api.nvim_buf_is_valid(bufnr) and bufnr or nil,
modeline = false,
data = { client_id = self.id, request_id = request_id, request = request },
})
self:_process_request(request_id, 'pending', bufnr, method)
end
return success, request_id
@ -715,7 +716,7 @@ end
--- @param params table LSP request params.
--- @param timeout_ms integer? Maximum time in milliseconds to wait for
--- a result. Defaults to 1000
--- @param bufnr integer Buffer handle (0 for current).
--- @param bufnr? integer (default: 0) Buffer handle, or 0 for current.
--- @return {err: lsp.ResponseError?, result:any}? `result` and `err` from the |lsp-handler|.
--- `nil` is the request was unsuccessful
--- @return string? err On timeout, cancel or error, where `err` is a
@ -780,16 +781,7 @@ end
--- @return boolean status indicating if the notification was successful.
--- @see |Client:notify()|
function Client:cancel_request(id)
validate('id', id, 'number')
local request = self.requests[id]
if request and request.type == 'pending' then
request.type = 'cancel'
api.nvim_exec_autocmds('LspRequest', {
buffer = api.nvim_buf_is_valid(request.bufnr) and request.bufnr or nil,
modeline = false,
data = { client_id = self.id, request_id = id, request = request },
})
end
self:_process_request(id, 'cancel')
return self.rpc.notify(ms.dollar_cancelRequest, { id = id })
end
@ -903,7 +895,7 @@ end
--- @param bufnr? integer
--- @return lsp.Registration?
function Client:_get_registration(method, bufnr)
bufnr = bufnr or vim.api.nvim_get_current_buf()
bufnr = vim._resolve_bufnr(bufnr)
for _, reg in ipairs(self.registrations[method] or {}) do
if not reg.registerOptions or not reg.registerOptions.documentSelector then
return reg
@ -940,7 +932,7 @@ end
--- @param handler? lsp.Handler only called if a server command
function Client:exec_cmd(command, context, handler)
context = vim.deepcopy(context or {}, true) --[[@as lsp.HandlerContext]]
context.bufnr = context.bufnr or api.nvim_get_current_buf()
context.bufnr = vim._resolve_bufnr(context.bufnr)
context.client_id = self.id
local cmdname = command.command
local fn = self.commands[cmdname] or lsp.commands[cmdname]
@ -1171,7 +1163,7 @@ function Client:_add_workspace_folder(dir)
end
end
local wf = assert(get_workspace_folders(dir))
local wf = assert(lsp._get_workspace_folders(dir))
self:notify(ms.workspace_didChangeWorkspaceFolders, {
event = { added = wf, removed = {} },
@ -1186,7 +1178,7 @@ end
--- Remove a directory to the workspace folders.
--- @param dir string?
function Client:_remove_workspace_folder(dir)
local wf = assert(get_workspace_folders(dir))
local wf = assert(lsp._get_workspace_folders(dir))
self:notify(ms.workspace_didChangeWorkspaceFolders, {
event = { added = {}, removed = wf },

View File

@ -104,16 +104,12 @@ function M.run()
end
end
local function resolve_bufnr(bufnr)
return bufnr == 0 and api.nvim_get_current_buf() or bufnr
end
--- Clear the lenses
---
---@param client_id integer|nil filter by client_id. All clients if nil
---@param bufnr integer|nil filter by buffer. All buffers if nil, 0 for current buffer
function M.clear(client_id, bufnr)
bufnr = bufnr and resolve_bufnr(bufnr)
bufnr = bufnr and vim._resolve_bufnr(bufnr)
local buffers = bufnr and { bufnr }
or vim.tbl_filter(api.nvim_buf_is_loaded, api.nvim_list_bufs())
for _, iter_bufnr in pairs(buffers) do
@ -296,7 +292,7 @@ end
--- @param opts? vim.lsp.codelens.refresh.Opts Optional fields
function M.refresh(opts)
opts = opts or {}
local bufnr = opts.bufnr and resolve_bufnr(opts.bufnr)
local bufnr = opts.bufnr and vim._resolve_bufnr(opts.bufnr)
local buffers = bufnr and { bufnr }
or vim.tbl_filter(api.nvim_buf_is_loaded, api.nvim_list_bufs())

View File

@ -550,7 +550,7 @@ local function on_complete_done()
return
end
local offset_encoding = client.offset_encoding or 'utf-16'
local position_encoding = client.offset_encoding or 'utf-16'
local resolve_provider = (client.server_capabilities.completionProvider or {}).resolveProvider
local function clear_word()
@ -576,7 +576,7 @@ local function on_complete_done()
if completion_item.additionalTextEdits and next(completion_item.additionalTextEdits) then
clear_word()
lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, offset_encoding)
lsp.util.apply_text_edits(completion_item.additionalTextEdits, bufnr, position_encoding)
apply_snippet_and_command()
elseif resolve_provider and type(completion_item) == 'table' then
local changedtick = vim.b[bufnr].changedtick
@ -591,7 +591,7 @@ local function on_complete_done()
if err then
vim.notify_once(err.message, vim.log.levels.WARN)
elseif result and result.additionalTextEdits then
lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, offset_encoding)
lsp.util.apply_text_edits(result.additionalTextEdits, bufnr, position_encoding)
if result.command then
completion_item.command = result.command
end
@ -716,7 +716,7 @@ end
--- @param bufnr integer Buffer handle, or 0 for the current buffer
--- @param opts? vim.lsp.completion.BufferOpts
function M.enable(enable, client_id, bufnr, opts)
bufnr = (bufnr == 0 and api.nvim_get_current_buf()) or bufnr
bufnr = vim._resolve_bufnr(bufnr)
if enable then
enable_completions(client_id, bufnr, opts or {})

View File

@ -77,7 +77,7 @@ end
local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
local buf_lines = get_buf_lines(bufnr)
local client = vim.lsp.get_client_by_id(client_id)
local offset_encoding = client and client.offset_encoding or 'utf-16'
local position_encoding = client and client.offset_encoding or 'utf-16'
--- @param diagnostic lsp.Diagnostic
--- @return vim.Diagnostic
return vim.tbl_map(function(diagnostic)
@ -95,9 +95,9 @@ local function diagnostic_lsp_to_vim(diagnostics, bufnr, client_id)
--- @type vim.Diagnostic
return {
lnum = start.line,
col = vim.str_byteindex(line, offset_encoding, start.character, false),
col = vim.str_byteindex(line, position_encoding, start.character, false),
end_lnum = _end.line,
end_col = vim.str_byteindex(line, offset_encoding, _end.character, false),
end_col = vim.str_byteindex(line, position_encoding, _end.character, false),
severity = severity_lsp_to_vim(diagnostic.severity),
message = message,
source = diagnostic.source,
@ -246,10 +246,18 @@ end
---
--- See |vim.diagnostic.config()| for configuration options.
---
---@param _ lsp.ResponseError?
---@param error lsp.ResponseError?
---@param result lsp.DocumentDiagnosticReport
---@param ctx lsp.HandlerContext
function M.on_diagnostic(_, result, ctx)
function M.on_diagnostic(error, result, ctx)
if error ~= nil and error.code == protocol.ErrorCodes.ServerCancelled then
if error.data == nil or error.data.retriggerRequest ~= false then
local client = assert(vim.lsp.get_client_by_id(ctx.client_id))
client:request(ctx.method, ctx.params)
end
return
end
if result == nil or result.kind == 'unchanged' then
return
end
@ -348,9 +356,7 @@ end
---@param bufnr (integer) Buffer handle, or 0 for current
---@private
function M._enable(bufnr)
if bufnr == nil or bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
if not bufstates[bufnr] then
bufstates[bufnr] = { enabled = true }

View File

@ -659,7 +659,8 @@ for k, fn in pairs(M) do
})
end
if err then
-- ServerCancelled errors should be propagated to the request handler
if err and err.code ~= protocol.ErrorCodes.ServerCancelled then
-- LSP spec:
-- interface ResponseError:
-- code: integer;

View File

@ -28,42 +28,45 @@ local function check_log()
report_fn(string.format('Log size: %d KB', log_size / 1000))
end
--- @param f function
--- @return string
local function func_tostring(f)
local info = debug.getinfo(f, 'S')
return ('<function %s:%s>'):format(info.source, info.linedefined)
end
local function check_active_clients()
vim.health.start('vim.lsp: Active Clients')
local clients = vim.lsp.get_clients()
if next(clients) then
for _, client in pairs(clients) do
local cmd ---@type string
if type(client.config.cmd) == 'table' then
cmd = table.concat(client.config.cmd --[[@as table]], ' ')
elseif type(client.config.cmd) == 'function' then
cmd = tostring(client.config.cmd)
local ccmd = client.config.cmd
if type(ccmd) == 'table' then
cmd = vim.inspect(ccmd)
elseif type(ccmd) == 'function' then
cmd = func_tostring(ccmd)
end
local dirs_info ---@type string
if client.workspace_folders and #client.workspace_folders > 1 then
dirs_info = string.format(
' Workspace folders:\n %s',
vim
.iter(client.workspace_folders)
---@param folder lsp.WorkspaceFolder
:map(function(folder)
return folder.name
end)
:join('\n ')
)
local wfolders = {} --- @type string[]
for _, dir in ipairs(client.workspace_folders) do
wfolders[#wfolders + 1] = dir.name
end
dirs_info = ('- Workspace folders:\n %s'):format(table.concat(wfolders, '\n '))
else
dirs_info = string.format(
' Root directory: %s',
'- Root directory: %s',
client.root_dir and vim.fn.fnamemodify(client.root_dir, ':~')
) or nil
end
report_info(table.concat({
string.format('%s (id: %d)', client.name, client.id),
dirs_info,
string.format(' Command: %s', cmd),
string.format(' Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
string.format('- Command: %s', cmd),
string.format('- Settings: %s', vim.inspect(client.settings, { newline = '\n ' })),
string.format(
' Attached buffers: %s',
'- Attached buffers: %s',
vim.iter(pairs(client.attached_buffers)):map(tostring):join(', ')
),
}, '\n'))
@ -174,10 +177,45 @@ local function check_position_encodings()
end
end
local function check_enabled_configs()
vim.health.start('vim.lsp: Enabled Configurations')
for name in vim.spairs(vim.lsp._enabled_configs) do
local config = vim.lsp._resolve_config(name)
local text = {} --- @type string[]
text[#text + 1] = ('%s:'):format(name)
for k, v in
vim.spairs(config --[[@as table<string,any>]])
do
local v_str --- @type string?
if k == 'name' then
v_str = nil
elseif k == 'filetypes' or k == 'root_markers' then
v_str = table.concat(v, ', ')
elseif type(v) == 'function' then
v_str = func_tostring(v)
else
v_str = vim.inspect(v, { newline = '\n ' })
end
if k == 'cmd' and type(v) == 'table' and vim.fn.executable(v[1]) == 0 then
report_warn(("'%s' is not executable. Configuration will not be used."):format(v[1]))
end
if v_str then
text[#text + 1] = ('- %s: %s'):format(k, v_str)
end
end
text[#text + 1] = ''
report_info(table.concat(text, '\n'))
end
end
--- Performs a healthcheck for LSP
function M.check()
check_log()
check_active_clients()
check_enabled_configs()
check_watcher()
check_position_encodings()
end

View File

@ -149,8 +149,8 @@ function M.get(filter)
vim.list_extend(hints, M.get(vim.tbl_extend('keep', { bufnr = buf }, filter)))
end, vim.api.nvim_list_bufs())
return hints
elseif bufnr == 0 then
bufnr = api.nvim_get_current_buf()
else
bufnr = vim._resolve_bufnr(bufnr)
end
local bufstate = bufstates[bufnr]
@ -203,9 +203,7 @@ end
--- Clear inlay hints
---@param bufnr (integer) Buffer handle, or 0 for current
local function clear(bufnr)
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
local bufstate = bufstates[bufnr]
local client_lens = (bufstate or {}).client_hints or {}
local client_ids = vim.tbl_keys(client_lens) --- @type integer[]
@ -221,9 +219,7 @@ end
--- Disable inlay hints for a buffer
---@param bufnr (integer) Buffer handle, or 0 for current
local function _disable(bufnr)
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
clear(bufnr)
bufstates[bufnr] = nil
bufstates[bufnr].enabled = false
@ -242,9 +238,7 @@ end
--- Enable inlay hints for a buffer
---@param bufnr (integer) Buffer handle, or 0 for current
local function _enable(bufnr)
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
bufstates[bufnr] = nil
bufstates[bufnr].enabled = true
_refresh(bufnr)
@ -371,13 +365,10 @@ function M.is_enabled(filter)
filter = filter or {}
local bufnr = filter.bufnr
vim.validate('bufnr', bufnr, 'number', true)
if bufnr == nil then
return globalstate.enabled
elseif bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
return bufstates[bufnr].enabled
return bufstates[vim._resolve_bufnr(bufnr)].enabled
end
--- Optional filters |kwargs|, or `nil` for all.

View File

@ -174,6 +174,7 @@ local constants = {
-- Defined by the protocol.
RequestCancelled = -32800,
ContentModified = -32801,
ServerCancelled = -32802,
},
-- Describes the content type that a client supports in various
@ -439,6 +440,13 @@ function protocol.make_client_capabilities()
properties = { 'command' },
},
},
foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true,
foldingRange = {
collapsedText = true,
},
},
formatting = {
dynamicRegistration = true,
},

View File

@ -1,18 +1,8 @@
local uv = vim.uv
local log = require('vim.lsp.log')
local protocol = require('vim.lsp.protocol')
local lsp_transport = require('vim.lsp._transport')
local validate, schedule_wrap = vim.validate, vim.schedule_wrap
local is_win = vim.fn.has('win32') == 1
--- Checks whether a given path exists and is a directory.
---@param filename string path to check
---@return boolean
local function is_dir(filename)
local stat = uv.fs_stat(filename)
return stat and stat.type == 'directory' or false
end
--- Embeds the given string into a table and correctly computes `Content-Length`.
---
---@param message string
@ -242,8 +232,11 @@ local default_dispatchers = {
end,
}
---@private
function M.create_read_loop(handle_body, on_no_chunk, on_error)
--- @private
--- @param handle_body fun(body: string)
--- @param on_exit? fun()
--- @param on_error fun(err: any)
function M.create_read_loop(handle_body, on_exit, on_error)
local parse_chunk = coroutine.wrap(request_parser_loop) --[[@as fun(chunk: string?): vim.lsp.rpc.Headers?, string?]]
parse_chunk()
return function(err, chunk)
@ -253,8 +246,8 @@ function M.create_read_loop(handle_body, on_no_chunk, on_error)
end
if not chunk then
if on_no_chunk then
on_no_chunk()
if on_exit then
on_exit()
end
return
end
@ -262,7 +255,7 @@ function M.create_read_loop(handle_body, on_no_chunk, on_error)
while true do
local headers, body = parse_chunk(chunk)
if headers then
handle_body(body)
handle_body(assert(body))
chunk = ''
else
break
@ -282,14 +275,14 @@ local Client = {}
---@private
function Client:encode_and_send(payload)
log.debug('rpc.send', payload)
if self.transport.is_closing() then
if self.transport:is_closing() then
return false
end
local jsonstr = assert(
vim.json.encode(payload),
string.format("Couldn't encode payload '%s'", vim.inspect(payload))
)
self.transport.write(format_message_with_content_length(jsonstr))
self.transport:write(format_message_with_content_length(jsonstr))
return true
end
@ -323,7 +316,7 @@ end
---@param method string The invoked LSP method
---@param params table? Parameters for the invoked LSP method
---@param callback fun(err?: lsp.ResponseError, result: any) Callback to invoke
---@param notify_reply_callback fun(message_id: integer)|nil Callback to invoke as soon as a request is no longer pending
---@param notify_reply_callback? fun(message_id: integer) Callback to invoke as soon as a request is no longer pending
---@return boolean success `true` if request could be sent, `false` if not
---@return integer? message_id if request could be sent, `nil` if not
function Client:request(method, params, callback, notify_reply_callback)
@ -337,21 +330,16 @@ function Client:request(method, params, callback, notify_reply_callback)
method = method,
params = params,
})
local message_callbacks = self.message_callbacks
local notify_reply_callbacks = self.notify_reply_callbacks
if result then
if message_callbacks then
message_callbacks[message_id] = schedule_wrap(callback)
else
return false, nil
end
if notify_reply_callback and notify_reply_callbacks then
notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback)
end
return result, message_id
else
return false, nil
if not result then
return false
end
self.message_callbacks[message_id] = schedule_wrap(callback)
if notify_reply_callback then
self.notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback)
end
return result, message_id
end
---@package
@ -370,7 +358,7 @@ end
---@param ... any
---@return boolean status
---@return any head
---@return any|nil ...
---@return any? ...
function Client:pcall_handler(errkind, status, head, ...)
if not status then
self:on_error(errkind, head, ...)
@ -385,7 +373,7 @@ end
---@param ... any
---@return boolean status
---@return any head
---@return any|nil ...
---@return any? ...
function Client:try_call(errkind, fn, ...)
return self:pcall_handler(errkind, pcall(fn, ...))
end
@ -394,7 +382,8 @@ end
-- time and log them. This would require storing the timestamp. I could call
-- them with an error then, perhaps.
---@package
--- @package
--- @param body string
function Client:handle_body(body)
local ok, decoded = pcall(vim.json.decode, body, { luanil = { object = true } })
if not ok then
@ -406,7 +395,7 @@ function Client:handle_body(body)
if type(decoded) ~= 'table' then
self:on_error(M.client_errors.INVALID_SERVER_MESSAGE, decoded)
elseif type(decoded.method) == 'string' and decoded.id then
local err --- @type lsp.ResponseError|nil
local err --- @type lsp.ResponseError?
-- Schedule here so that the users functions don't trigger an error and
-- we can still use the result.
vim.schedule(coroutine.wrap(function()
@ -453,45 +442,36 @@ function Client:handle_body(body)
local result_id = assert(tonumber(decoded.id), 'response id must be a number')
-- Notify the user that a response was received for the request
local notify_reply_callbacks = self.notify_reply_callbacks
local notify_reply_callback = notify_reply_callbacks and notify_reply_callbacks[result_id]
local notify_reply_callback = self.notify_reply_callbacks[result_id]
if notify_reply_callback then
validate('notify_reply_callback', notify_reply_callback, 'function')
notify_reply_callback(result_id)
notify_reply_callbacks[result_id] = nil
self.notify_reply_callbacks[result_id] = nil
end
local message_callbacks = self.message_callbacks
-- Do not surface RequestCancelled to users, it is RPC-internal.
if decoded.error then
local mute_error = false
assert(type(decoded.error) == 'table')
if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
log.debug('Received cancellation ack', decoded)
mute_error = true
end
if mute_error then
-- Clear any callback since this is cancelled now.
-- This is safe to do assuming that these conditions hold:
-- - The server will not send a result callback after this cancellation.
-- - If the server sent this cancellation ACK after sending the result, the user of this RPC
-- client will ignore the result themselves.
if result_id and message_callbacks then
message_callbacks[result_id] = nil
if result_id then
self.message_callbacks[result_id] = nil
end
return
end
end
local callback = message_callbacks and message_callbacks[result_id]
local callback = self.message_callbacks[result_id]
if callback then
message_callbacks[result_id] = nil
self.message_callbacks[result_id] = nil
validate('callback', callback, 'function')
if decoded.error then
decoded.error = setmetatable(decoded.error, {
__tostring = M.format_rpc_error,
})
setmetatable(decoded.error, { __tostring = M.format_rpc_error })
end
self:try_call(
M.client_errors.SERVER_RESULT_CALLBACK_ERROR,
@ -517,11 +497,6 @@ function Client:handle_body(body)
end
end
---@class (private) vim.lsp.rpc.Transport
---@field write fun(msg: string)
---@field is_closing fun(): boolean
---@field terminate fun()
---@param dispatchers vim.lsp.rpc.Dispatchers
---@param transport vim.lsp.rpc.Transport
---@return vim.lsp.rpc.Client
@ -536,11 +511,20 @@ local function new_client(dispatchers, transport)
return setmetatable(state, { __index = Client })
end
---@class vim.lsp.rpc.PublicClient
---@field request fun(method: string, params: table?, callback: fun(err: lsp.ResponseError|nil, result: any), notify_reply_callback: fun(message_id: integer)|nil):boolean,integer? see |vim.lsp.rpc.request()|
---@field notify fun(method: string, params: any):boolean see |vim.lsp.rpc.notify()|
---@field is_closing fun(): boolean
---@field terminate fun()
--- Client RPC object
--- @class vim.lsp.rpc.PublicClient
---
--- See [vim.lsp.rpc.request()]
--- @field request fun(method: string, params: table?, callback: fun(err?: lsp.ResponseError, result: any), notify_reply_callback?: fun(message_id: integer)):boolean,integer?
---
--- See [vim.lsp.rpc.notify()]
--- @field notify fun(method: string, params: any): boolean
---
--- Indicates if the RPC is closing.
--- @field is_closing fun(): boolean
---
--- Terminates the RPC client.
--- @field terminate fun()
---@param client vim.lsp.rpc.Client
---@return vim.lsp.rpc.PublicClient
@ -551,20 +535,20 @@ local function public_client(client)
---@private
function result.is_closing()
return client.transport.is_closing()
return client.transport:is_closing()
end
---@private
function result.terminate()
client.transport.terminate()
client.transport:terminate()
end
--- Sends a request to the LSP server and runs {callback} upon response.
---
---@param method (string) The invoked LSP method
---@param params (table?) Parameters for the invoked LSP method
---@param callback fun(err: lsp.ResponseError|nil, result: any) Callback to invoke
---@param notify_reply_callback fun(message_id: integer)|nil Callback to invoke as soon as a request is no longer pending
---@param callback fun(err: lsp.ResponseError?, result: any) Callback to invoke
---@param notify_reply_callback? fun(message_id: integer) Callback to invoke as soon as a request is no longer pending
---@return boolean success `true` if request could be sent, `false` if not
---@return integer? message_id if request could be sent, `nil` if not
function result.request(method, params, callback, notify_reply_callback)
@ -610,6 +594,21 @@ local function merge_dispatchers(dispatchers)
return merged
end
--- @param client vim.lsp.rpc.Client
--- @param on_exit? fun()
local function create_client_read_loop(client, on_exit)
--- @param body string
local function handle_body(body)
client:handle_body(body)
end
local function on_error(err)
client:on_error(M.client_errors.READ_ERROR, err)
end
return M.create_read_loop(handle_body, on_exit, on_error)
end
--- Create a LSP RPC client factory that connects to either:
---
--- - a named pipe (windows)
@ -617,83 +616,26 @@ end
--- - a host and port via TCP
---
--- Return a function that can be passed to the `cmd` field for
--- |vim.lsp.start_client()| or |vim.lsp.start()|.
--- |vim.lsp.start()|.
---
---@param host_or_path string host to connect to or path to a pipe/domain socket
---@param port integer? TCP port to connect to. If absent the first argument must be a pipe
---@return fun(dispatchers: vim.lsp.rpc.Dispatchers): vim.lsp.rpc.PublicClient
function M.connect(host_or_path, port)
validate('host_or_path', host_or_path, 'string')
validate('port', port, 'number', true)
return function(dispatchers)
validate('dispatchers', dispatchers, 'table', true)
dispatchers = merge_dispatchers(dispatchers)
local handle = (
port == nil
and assert(
uv.new_pipe(false),
string.format('Pipe with name %s could not be opened.', host_or_path)
)
or assert(uv.new_tcp(), 'Could not create new TCP socket')
)
local closing = false
-- Connect returns a PublicClient synchronously so the caller
-- can immediately send messages before the connection is established
-- -> Need to buffer them until that happens
local connected = false
-- size should be enough because the client can't really do anything until initialization is done
-- which required a response from the server - implying the connection got established
local msgbuf = vim.ringbuf(10)
local transport = {
write = function(msg)
if connected then
local _, err = handle:write(msg)
if err and not closing then
log.error('Error on handle:write: %q', err)
end
else
msgbuf:push(msg)
end
end,
is_closing = function()
return closing
end,
terminate = function()
if not closing then
closing = true
handle:shutdown()
handle:close()
dispatchers.on_exit(0, 0)
end
end,
}
local transport = lsp_transport.TransportConnect.new()
local client = new_client(dispatchers, transport)
local function on_connect(err)
if err then
local address = port == nil and host_or_path or (host_or_path .. ':' .. port)
vim.schedule(function()
vim.notify(
string.format('Could not connect to %s, reason: %s', address, vim.inspect(err)),
vim.log.levels.WARN
)
end)
return
end
local handle_body = function(body)
client:handle_body(body)
end
handle:read_start(M.create_read_loop(handle_body, transport.terminate, function(read_err)
client:on_error(M.client_errors.READ_ERROR, read_err)
end))
connected = true
for msg in msgbuf do
handle:write(msg)
end
end
if port == nil then
handle:connect(host_or_path, on_connect)
else
local info = uv.getaddrinfo(host_or_path, nil)
local resolved_host = info and info[1] and info[1].addr or host_or_path
handle:connect(resolved_host, port, on_connect)
end
local on_read = create_client_read_loop(client, function()
transport:terminate()
end)
transport:connect(host_or_path, port, on_read, dispatchers.on_exit)
return public_client(client)
end
@ -713,83 +655,19 @@ end
--- @param cmd string[] Command to start the LSP server.
--- @param dispatchers? vim.lsp.rpc.Dispatchers
--- @param extra_spawn_params? vim.lsp.rpc.ExtraSpawnParams
--- @return vim.lsp.rpc.PublicClient : Client RPC object, with these methods:
--- - `notify()` |vim.lsp.rpc.notify()|
--- - `request()` |vim.lsp.rpc.request()|
--- - `is_closing()` returns a boolean indicating if the RPC is closing.
--- - `terminate()` terminates the RPC client.
--- @return vim.lsp.rpc.PublicClient
function M.start(cmd, dispatchers, extra_spawn_params)
log.info('Starting RPC client', { cmd = cmd, extra = extra_spawn_params })
validate('cmd', cmd, 'table')
validate('dispatchers', dispatchers, 'table', true)
extra_spawn_params = extra_spawn_params or {}
if extra_spawn_params.cwd then
assert(is_dir(extra_spawn_params.cwd), 'cwd must be a directory')
end
dispatchers = merge_dispatchers(dispatchers)
local sysobj ---@type vim.SystemObj
local client = new_client(dispatchers, {
write = function(msg)
sysobj:write(msg)
end,
is_closing = function()
return sysobj == nil or sysobj:is_closing()
end,
terminate = function()
sysobj:kill(15)
end,
})
local handle_body = function(body)
client:handle_body(body)
end
local stdout_handler = M.create_read_loop(handle_body, nil, function(err)
client:on_error(M.client_errors.READ_ERROR, err)
end)
local stderr_handler = function(_, chunk)
if chunk then
log.error('rpc', cmd[1], 'stderr', chunk)
end
end
local detached = not is_win
if extra_spawn_params.detached ~= nil then
detached = extra_spawn_params.detached
end
local ok, sysobj_or_err = pcall(vim.system, cmd, {
stdin = true,
stdout = stdout_handler,
stderr = stderr_handler,
cwd = extra_spawn_params.cwd,
env = extra_spawn_params.env,
detach = detached,
}, function(obj)
dispatchers.on_exit(obj.code, obj.signal)
end)
if not ok then
local err = sysobj_or_err --[[@as string]]
local sfx --- @type string
if string.match(err, 'ENOENT') then
sfx = '. The language server is either not installed, missing from PATH, or not executable.'
else
sfx = string.format(' with error message: %s', err)
end
local msg =
string.format('Spawning language server with cmd: `%s` failed%s', vim.inspect(cmd), sfx)
error(msg)
end
sysobj = sysobj_or_err --[[@as vim.SystemObj]]
local transport = lsp_transport.TransportRun.new()
local client = new_client(dispatchers, transport)
local on_read = create_client_read_loop(client)
transport:run(cmd, extra_spawn_params, on_read, dispatchers.on_exit)
return public_client(client)
end

View File

@ -600,9 +600,7 @@ function M.start(bufnr, client_id, opts)
vim.validate('bufnr', bufnr, 'number')
vim.validate('client_id', client_id, 'number')
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
opts = opts or {}
assert(
@ -655,9 +653,7 @@ function M.stop(bufnr, client_id)
vim.validate('bufnr', bufnr, 'number')
vim.validate('client_id', client_id, 'number')
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
local highlighter = STHighlighter.active[bufnr]
if not highlighter then
@ -691,9 +687,7 @@ end
--- - modifiers (table) token modifiers as a set. E.g., { static = true, readonly = true }
--- - client_id (integer)
function M.get_at_pos(bufnr, row, col)
if bufnr == nil or bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
local highlighter = STHighlighter.active[bufnr]
if not highlighter then
@ -739,8 +733,7 @@ function M.force_refresh(bufnr)
vim.validate('bufnr', bufnr, 'number', true)
local buffers = bufnr == nil and vim.tbl_keys(STHighlighter.active)
or bufnr == 0 and { api.nvim_get_current_buf() }
or { bufnr }
or { vim._resolve_bufnr(bufnr) }
for _, buffer in ipairs(buffers) do
local highlighter = STHighlighter.active[buffer]
@ -770,9 +763,7 @@ end
---@param hl_group (string) Highlight group name
---@param opts? vim.lsp.semantic_tokens.highlight_token.Opts Optional parameters:
function M.highlight_token(token, bufnr, client_id, hl_group, opts)
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
local highlighter = STHighlighter.active[bufnr]
if not highlighter then
return

View File

@ -48,21 +48,21 @@ local str_utfindex = vim.str_utfindex
local str_utf_start = vim.str_utf_start
local str_utf_end = vim.str_utf_end
-- Given a line, byte idx, alignment, and offset_encoding convert to the aligned
-- Given a line, byte idx, alignment, and position_encoding convert to the aligned
-- utf-8 index and either the utf-16, or utf-32 index.
---@param line string the line to index into
---@param byte integer the byte idx
---@param offset_encoding string utf-8|utf-16|utf-32|nil (default: utf-8)
---@param position_encoding string utf-8|utf-16|utf-32|nil (default: utf-8)
---@return integer byte_idx of first change position
---@return integer char_idx of first change position
local function align_end_position(line, byte, offset_encoding)
local function align_end_position(line, byte, position_encoding)
local char --- @type integer
-- If on the first byte, or an empty string: the trivial case
if byte == 1 or #line == 0 then
char = byte
-- Called in the case of extending an empty line "" -> "a"
elseif byte == #line + 1 then
char = str_utfindex(line, offset_encoding) + 1
char = str_utfindex(line, position_encoding) + 1
else
-- Modifying line, find the nearest utf codepoint
local offset = str_utf_start(line, byte)
@ -73,9 +73,9 @@ local function align_end_position(line, byte, offset_encoding)
end
if byte <= #line then
--- Convert to 0 based for input, and from 0 based for output
char = str_utfindex(line, offset_encoding, byte - 1) + 1
char = str_utfindex(line, position_encoding, byte - 1) + 1
else
char = str_utfindex(line, offset_encoding) + 1
char = str_utfindex(line, position_encoding) + 1
end
-- Extending line, find the nearest utf codepoint for the last valid character
end
@ -93,7 +93,7 @@ end
---@param firstline integer firstline from on_lines, adjusted to 1-index
---@param lastline integer lastline from on_lines, adjusted to 1-index
---@param new_lastline integer new_lastline from on_lines, adjusted to 1-index
---@param offset_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8)
---@param position_encoding string utf-8|utf-16|utf-32|nil (fallback to utf-8)
---@return vim.lsp.sync.Range result table include line_idx, byte_idx, and char_idx of first change position
local function compute_start_range(
prev_lines,
@ -101,7 +101,7 @@ local function compute_start_range(
firstline,
lastline,
new_lastline,
offset_encoding
position_encoding
)
local char_idx --- @type integer?
local byte_idx --- @type integer?
@ -115,7 +115,7 @@ local function compute_start_range(
if line then
line_idx = firstline - 1
byte_idx = #line + 1
char_idx = str_utfindex(line, offset_encoding) + 1
char_idx = str_utfindex(line, position_encoding) + 1
else
line_idx = firstline
byte_idx = 1
@ -152,11 +152,11 @@ local function compute_start_range(
char_idx = 1
elseif start_byte_idx == #prev_line + 1 then
byte_idx = start_byte_idx
char_idx = str_utfindex(prev_line, offset_encoding) + 1
char_idx = str_utfindex(prev_line, position_encoding) + 1
else
byte_idx = start_byte_idx + str_utf_start(prev_line, start_byte_idx)
--- Convert to 0 based for input, and from 0 based for output
char_idx = vim.str_utfindex(prev_line, offset_encoding, byte_idx - 1) + 1
char_idx = vim.str_utfindex(prev_line, position_encoding, byte_idx - 1) + 1
end
-- Return the start difference (shared for new and prev lines)
@ -174,7 +174,7 @@ end
---@param firstline integer
---@param lastline integer
---@param new_lastline integer
---@param offset_encoding string
---@param position_encoding string
---@return vim.lsp.sync.Range prev_end_range
---@return vim.lsp.sync.Range curr_end_range
local function compute_end_range(
@ -184,7 +184,7 @@ local function compute_end_range(
firstline,
lastline,
new_lastline,
offset_encoding
position_encoding
)
-- A special case for the following `firstline == new_lastline` case where lines are deleted.
-- Even if the buffer has become empty, nvim behaves as if it has an empty line with eol.
@ -193,7 +193,7 @@ local function compute_end_range(
return {
line_idx = lastline - 1,
byte_idx = #prev_line + 1,
char_idx = str_utfindex(prev_line, offset_encoding) + 1,
char_idx = str_utfindex(prev_line, position_encoding) + 1,
}, { line_idx = 1, byte_idx = 1, char_idx = 1 }
end
-- If firstline == new_lastline, the first change occurred on a line that was deleted.
@ -259,7 +259,7 @@ local function compute_end_range(
prev_end_byte_idx = 1
end
local prev_byte_idx, prev_char_idx =
align_end_position(prev_line, prev_end_byte_idx, offset_encoding)
align_end_position(prev_line, prev_end_byte_idx, position_encoding)
local prev_end_range =
{ line_idx = prev_line_idx, byte_idx = prev_byte_idx, char_idx = prev_char_idx }
@ -274,7 +274,7 @@ local function compute_end_range(
curr_end_byte_idx = 1
end
local curr_byte_idx, curr_char_idx =
align_end_position(curr_line, curr_end_byte_idx, offset_encoding)
align_end_position(curr_line, curr_end_byte_idx, position_encoding)
curr_end_range =
{ line_idx = curr_line_idx, byte_idx = curr_byte_idx, char_idx = curr_char_idx }
end
@ -317,7 +317,7 @@ local function extract_text(lines, start_range, end_range, line_ending)
end
end
-- rangelength depends on the offset encoding
-- rangelength depends on the position encoding
-- bytes for utf-8 (clangd with extension)
-- codepoints for utf-16
-- codeunits for utf-32
@ -326,10 +326,10 @@ end
---@param lines string[]
---@param start_range vim.lsp.sync.Range
---@param end_range vim.lsp.sync.Range
---@param offset_encoding string
---@param position_encoding string
---@param line_ending string
---@return integer
local function compute_range_length(lines, start_range, end_range, offset_encoding, line_ending)
local function compute_range_length(lines, start_range, end_range, position_encoding, line_ending)
local line_ending_length = #line_ending
-- Single line case
if start_range.line_idx == end_range.line_idx then
@ -339,7 +339,7 @@ local function compute_range_length(lines, start_range, end_range, offset_encodi
local start_line = lines[start_range.line_idx]
local range_length --- @type integer
if start_line and #start_line > 0 then
range_length = str_utfindex(start_line, offset_encoding)
range_length = str_utfindex(start_line, position_encoding)
- start_range.char_idx
+ 1
+ line_ending_length
@ -352,7 +352,7 @@ local function compute_range_length(lines, start_range, end_range, offset_encodi
for idx = start_range.line_idx + 1, end_range.line_idx - 1 do
-- Length full line plus newline character
if #lines[idx] > 0 then
range_length = range_length + str_utfindex(lines[idx], offset_encoding) + #line_ending
range_length = range_length + str_utfindex(lines[idx], position_encoding) + #line_ending
else
range_length = range_length + line_ending_length
end
@ -372,7 +372,7 @@ end
---@param firstline integer line to begin search for first difference
---@param lastline integer line to begin search in old_lines for last difference
---@param new_lastline integer line to begin search in new_lines for last difference
---@param offset_encoding string encoding requested by language server
---@param position_encoding string encoding requested by language server
---@param line_ending string
---@return lsp.TextDocumentContentChangeEvent : see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
function M.compute_diff(
@ -381,7 +381,7 @@ function M.compute_diff(
firstline,
lastline,
new_lastline,
offset_encoding,
position_encoding,
line_ending
)
-- Find the start of changes between the previous and current buffer. Common between both.
@ -393,7 +393,7 @@ function M.compute_diff(
firstline + 1,
lastline + 1,
new_lastline + 1,
offset_encoding
position_encoding
)
-- Find the last position changed in the previous and current buffer.
-- prev_end_range is sent to the server as as the end of the changed range.
@ -405,7 +405,7 @@ function M.compute_diff(
firstline + 1,
lastline + 1,
new_lastline + 1,
offset_encoding
position_encoding
)
-- Grab the changed text of from start_range to curr_end_range in the current buffer.
@ -414,7 +414,7 @@ function M.compute_diff(
-- Compute the range of the replaced text. Deprecated but still required for certain language servers
local range_length =
compute_range_length(prev_lines, start_range, prev_end_range, offset_encoding, line_ending)
compute_range_length(prev_lines, start_range, prev_end_range, position_encoding, line_ending)
-- convert to 0 based indexing
local result = {

View File

@ -192,9 +192,7 @@ local function get_lines(bufnr, rows)
rows = type(rows) == 'table' and rows or { rows }
-- This is needed for bufload and bufloaded
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
local function buf_lines()
local lines = {} --- @type table<integer,string>
@ -277,9 +275,9 @@ end
--- Position is a https://microsoft.github.io/language-server-protocol/specifications/specification-current/#position
---@param position lsp.Position
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@return integer
local function get_line_byte_from_position(bufnr, position, offset_encoding)
local function get_line_byte_from_position(bufnr, position, position_encoding)
-- LSP's line and characters are 0-indexed
-- Vim's line and columns are 1-indexed
local col = position.character
@ -287,7 +285,7 @@ local function get_line_byte_from_position(bufnr, position, offset_encoding)
-- character
if col > 0 then
local line = get_line(bufnr, position.line) or ''
return vim.str_byteindex(line, offset_encoding, col, false)
return vim.str_byteindex(line, position_encoding, col, false)
end
return col
end
@ -295,12 +293,12 @@ end
--- Applies a list of text edits to a buffer.
---@param text_edits lsp.TextEdit[]
---@param bufnr integer Buffer id
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textEdit
function M.apply_text_edits(text_edits, bufnr, offset_encoding)
function M.apply_text_edits(text_edits, bufnr, position_encoding)
validate('text_edits', text_edits, 'table', false)
validate('bufnr', bufnr, 'number', false)
validate('offset_encoding', offset_encoding, 'string', false)
validate('position_encoding', position_encoding, 'string', false)
if not next(text_edits) then
return
@ -359,9 +357,9 @@ function M.apply_text_edits(text_edits, bufnr, offset_encoding)
-- Convert from LSP style ranges to Neovim style ranges.
local start_row = text_edit.range.start.line
local start_col = get_line_byte_from_position(bufnr, text_edit.range.start, offset_encoding)
local start_col = get_line_byte_from_position(bufnr, text_edit.range.start, position_encoding)
local end_row = text_edit.range['end'].line
local end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], offset_encoding)
local end_col = get_line_byte_from_position(bufnr, text_edit.range['end'], position_encoding)
local text = vim.split(text_edit.newText, '\n', { plain = true })
local max = api.nvim_buf_line_count(bufnr)
@ -430,14 +428,14 @@ end
---
---@param text_document_edit lsp.TextDocumentEdit
---@param index? integer: Optional index of the edit, if from a list of edits (or nil, if not from a list)
---@param offset_encoding? 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding? 'utf-8'|'utf-16'|'utf-32'
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentEdit
function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
function M.apply_text_document_edit(text_document_edit, index, position_encoding)
local text_document = text_document_edit.textDocument
local bufnr = vim.uri_to_bufnr(text_document.uri)
if offset_encoding == nil then
if position_encoding == nil then
vim.notify_once(
'apply_text_document_edit must be called with valid offset encoding',
'apply_text_document_edit must be called with valid position encoding',
vim.log.levels.WARN
)
return
@ -459,7 +457,7 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding)
return
end
M.apply_text_edits(text_document_edit.edits, bufnr, offset_encoding)
M.apply_text_edits(text_document_edit.edits, bufnr, position_encoding)
end
local function path_components(path)
@ -619,12 +617,12 @@ end
--- Applies a `WorkspaceEdit`.
---
---@param workspace_edit lsp.WorkspaceEdit
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32' (required)
---@param position_encoding 'utf-8'|'utf-16'|'utf-32' (required)
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_applyEdit
function M.apply_workspace_edit(workspace_edit, offset_encoding)
if offset_encoding == nil then
function M.apply_workspace_edit(workspace_edit, position_encoding)
if position_encoding == nil then
vim.notify_once(
'apply_workspace_edit must be called with valid offset encoding',
'apply_workspace_edit must be called with valid position encoding',
vim.log.levels.WARN
)
return
@ -641,7 +639,7 @@ function M.apply_workspace_edit(workspace_edit, offset_encoding)
elseif change.kind then --- @diagnostic disable-line:undefined-field
error(string.format('Unsupported change: %q', vim.inspect(change)))
else
M.apply_text_document_edit(change, idx, offset_encoding)
M.apply_text_document_edit(change, idx, position_encoding)
end
end
return
@ -654,7 +652,7 @@ function M.apply_workspace_edit(workspace_edit, offset_encoding)
for uri, changes in pairs(all_changes) do
local bufnr = vim.uri_to_bufnr(uri)
M.apply_text_edits(changes, bufnr, offset_encoding)
M.apply_text_edits(changes, bufnr, position_encoding)
end
end
@ -904,17 +902,20 @@ end
--- Shows document and optionally jumps to the location.
---
---@param location lsp.Location|lsp.LocationLink
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'?
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'?
---@param opts? vim.lsp.util.show_document.Opts
---@return boolean `true` if succeeded
function M.show_document(location, offset_encoding, opts)
function M.show_document(location, position_encoding, opts)
-- location may be Location or LocationLink
local uri = location.uri or location.targetUri
if uri == nil then
return false
end
if offset_encoding == nil then
vim.notify_once('show_document must be called with valid offset encoding', vim.log.levels.WARN)
if position_encoding == nil then
vim.notify_once(
'show_document must be called with valid position encoding',
vim.log.levels.WARN
)
return false
end
local bufnr = vim.uri_to_bufnr(uri)
@ -946,7 +947,7 @@ function M.show_document(location, offset_encoding, opts)
if range then
-- Jump to new location (adjusting for encoding of characters)
local row = range.start.line
local col = get_line_byte_from_position(bufnr, range.start, offset_encoding)
local col = get_line_byte_from_position(bufnr, range.start, position_encoding)
api.nvim_win_set_cursor(win, { row + 1, col })
vim._with({ win = win }, function()
-- Open folds under the cursor
@ -961,12 +962,12 @@ end
---
---@deprecated use `vim.lsp.util.show_document` with `{focus=true}` instead
---@param location lsp.Location|lsp.LocationLink
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'?
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'?
---@param reuse_win boolean? Jump to existing window if buffer is already open.
---@return boolean `true` if the jump succeeded
function M.jump_to_location(location, offset_encoding, reuse_win)
function M.jump_to_location(location, position_encoding, reuse_win)
vim.deprecate('vim.lsp.util.jump_to_location', nil, '0.12')
return M.show_document(location, offset_encoding, { reuse_win = reuse_win, focus = true })
return M.show_document(location, position_encoding, { reuse_win = reuse_win, focus = true })
end
--- Previews a location in a floating window
@ -1661,18 +1662,18 @@ do --[[ References ]]
---
---@param bufnr integer Buffer id
---@param references lsp.DocumentHighlight[] objects to highlight
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@see https://microsoft.github.io/language-server-protocol/specification/#textDocumentContentChangeEvent
function M.buf_highlight_references(bufnr, references, offset_encoding)
function M.buf_highlight_references(bufnr, references, position_encoding)
validate('bufnr', bufnr, 'number', true)
validate('offset_encoding', offset_encoding, 'string', false)
validate('position_encoding', position_encoding, 'string', false)
for _, reference in ipairs(references) do
local range = reference.range
local start_line = range.start.line
local end_line = range['end'].line
local start_idx = get_line_byte_from_position(bufnr, range.start, offset_encoding)
local end_idx = get_line_byte_from_position(bufnr, range['end'], offset_encoding)
local start_idx = get_line_byte_from_position(bufnr, range.start, position_encoding)
local end_idx = get_line_byte_from_position(bufnr, range['end'], position_encoding)
local document_highlight_kind = {
[protocol.DocumentHighlightKind.Text] = 'LspReferenceText',
@ -1706,16 +1707,16 @@ end)
--- |setloclist()|.
---
---@param locations lsp.Location[]|lsp.LocationLink[]
---@param offset_encoding? 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding? 'utf-8'|'utf-16'|'utf-32'
--- default to first client of buffer
---@return vim.quickfix.entry[] # See |setqflist()| for the format
function M.locations_to_items(locations, offset_encoding)
if offset_encoding == nil then
function M.locations_to_items(locations, position_encoding)
if position_encoding == nil then
vim.notify_once(
'locations_to_items must be called with valid offset encoding',
'locations_to_items must be called with valid position encoding',
vim.log.levels.WARN
)
offset_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding
position_encoding = vim.lsp.get_clients({ bufnr = 0 })[1].offset_encoding
end
local items = {} --- @type vim.quickfix.entry[]
@ -1752,8 +1753,8 @@ function M.locations_to_items(locations, offset_encoding)
local end_row = end_pos.line
local line = lines[row] or ''
local end_line = lines[end_row] or ''
local col = vim.str_byteindex(line, offset_encoding, pos.character, false)
local end_col = vim.str_byteindex(end_line, offset_encoding, end_pos.character, false)
local col = vim.str_byteindex(line, position_encoding, pos.character, false)
local end_col = vim.str_byteindex(end_line, position_encoding, end_pos.character, false)
items[#items + 1] = {
filename = filename,
@ -1864,8 +1865,8 @@ function M.try_trim_markdown_code_blocks(lines)
end
---@param window integer?: window handle or 0 for current, defaults to current
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
local function make_position_param(window, offset_encoding)
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
local function make_position_param(window, position_encoding)
window = window or 0
local buf = api.nvim_win_get_buf(window)
local row, col = unpack(api.nvim_win_get_cursor(window))
@ -1875,7 +1876,7 @@ local function make_position_param(window, offset_encoding)
return { line = 0, character = 0 }
end
col = vim.str_utfindex(line, offset_encoding, col, false)
col = vim.str_utfindex(line, position_encoding, col, false)
return { line = row, character = col }
end
@ -1883,22 +1884,22 @@ end
--- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position.
---
---@param window integer?: window handle or 0 for current, defaults to current
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@return lsp.TextDocumentPositionParams
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
function M.make_position_params(window, offset_encoding)
function M.make_position_params(window, position_encoding)
window = window or 0
local buf = api.nvim_win_get_buf(window)
if offset_encoding == nil then
if position_encoding == nil then
vim.notify_once(
'warning: offset_encoding is required, using the offset_encoding from the first client',
'position_encoding param is required in vim.lsp.util.make_position_params. Defaulting to position encoding of the first client.',
vim.log.levels.WARN
)
offset_encoding = M._get_offset_encoding(buf)
position_encoding = M._get_offset_encoding(buf)
end
return {
textDocument = M.make_text_document_params(buf),
position = make_position_param(window, offset_encoding),
position = make_position_param(window, position_encoding),
}
end
@ -1941,18 +1942,18 @@ end
--- `textDocument/rangeFormatting`.
---
---@param window integer? window handle or 0 for current, defaults to current
---@param offset_encoding "utf-8"|"utf-16"|"utf-32"
---@param position_encoding "utf-8"|"utf-16"|"utf-32"
---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }
function M.make_range_params(window, offset_encoding)
function M.make_range_params(window, position_encoding)
local buf = api.nvim_win_get_buf(window or 0)
if offset_encoding == nil then
if position_encoding == nil then
vim.notify_once(
'warning: offset_encoding is required, using the offset_encoding from the first client',
'position_encoding param is required in vim.lsp.util.make_range_params. Defaulting to position encoding of the first client.',
vim.log.levels.WARN
)
offset_encoding = M._get_offset_encoding(buf)
position_encoding = M._get_offset_encoding(buf)
end
local position = make_position_param(window, offset_encoding)
local position = make_position_param(window, position_encoding)
return {
textDocument = M.make_text_document_params(buf),
range = { start = position, ['end'] = position },
@ -1967,19 +1968,19 @@ end
---@param end_pos [integer,integer]? {row,col} mark-indexed position.
--- Defaults to the end of the last visual selection.
---@param bufnr integer? buffer handle or 0 for current, defaults to current
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@return { textDocument: { uri: lsp.DocumentUri }, range: lsp.Range }
function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding)
function M.make_given_range_params(start_pos, end_pos, bufnr, position_encoding)
validate('start_pos', start_pos, 'table', true)
validate('end_pos', end_pos, 'table', true)
validate('offset_encoding', offset_encoding, 'string', true)
bufnr = bufnr or api.nvim_get_current_buf()
if offset_encoding == nil then
validate('position_encoding', position_encoding, 'string', true)
bufnr = vim._resolve_bufnr(bufnr)
if position_encoding == nil then
vim.notify_once(
'warning: offset_encoding is required, using the offset_encoding from the first client',
'position_encoding param is required in vim.lsp.util.make_given_range_params. Defaulting to position encoding of the first client.',
vim.log.levels.WARN
)
offset_encoding = M._get_offset_encoding(bufnr)
position_encoding = M._get_offset_encoding(bufnr)
end
--- @type [integer, integer]
local A = { unpack(start_pos or api.nvim_buf_get_mark(bufnr, '<')) }
@ -1988,12 +1989,12 @@ function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding)
-- convert to 0-index
A[1] = A[1] - 1
B[1] = B[1] - 1
-- account for offset_encoding.
-- account for position_encoding.
if A[2] > 0 then
A[2] = M.character_offset(bufnr, A[1], A[2], offset_encoding)
A[2] = M.character_offset(bufnr, A[1], A[2], position_encoding)
end
if B[2] > 0 then
B[2] = M.character_offset(bufnr, B[1], B[2], offset_encoding)
B[2] = M.character_offset(bufnr, B[1], B[2], position_encoding)
end
-- we need to offset the end character position otherwise we loose the last
-- character of the selection, as LSP end position is exclusive
@ -2100,9 +2101,9 @@ end
---@param bufnr integer
---@param start_line integer
---@param end_line integer
---@param offset_encoding 'utf-8'|'utf-16'|'utf-32'
---@param position_encoding 'utf-8'|'utf-16'|'utf-32'
---@return lsp.Range
local function make_line_range_params(bufnr, start_line, end_line, offset_encoding)
local function make_line_range_params(bufnr, start_line, end_line, position_encoding)
local last_line = api.nvim_buf_line_count(bufnr) - 1
---@type lsp.Position
@ -2111,7 +2112,12 @@ local function make_line_range_params(bufnr, start_line, end_line, offset_encodi
if end_line == last_line and not vim.bo[bufnr].endofline then
end_pos = {
line = end_line,
character = M.character_offset(bufnr, end_line, #get_line(bufnr, end_line), offset_encoding),
character = M.character_offset(
bufnr,
end_line,
#get_line(bufnr, end_line),
position_encoding
),
}
else
end_pos = { line = end_line + 1, character = 0 }
@ -2135,10 +2141,7 @@ end
---@param opts? vim.lsp.util._refresh.Opts Options table
function M._refresh(method, opts)
opts = opts or {}
local bufnr = opts.bufnr
if bufnr == nil or bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
local bufnr = vim._resolve_bufnr(opts.bufnr)
local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method, id = opts.client_id })
@ -2154,6 +2157,11 @@ function M._refresh(method, opts)
local first = vim.fn.line('w0', window)
local last = vim.fn.line('w$', window)
for _, client in ipairs(clients) do
for rid, req in pairs(client.requests) do
if req.method == method and req.type == 'pending' and req.bufnr == bufnr then
client:cancel_request(rid)
end
end
client:request(method, {
textDocument = textDocument,
range = make_line_range_params(bufnr, first - 1, last - 1, client.offset_encoding),

View File

@ -737,6 +737,51 @@ function vim.list_slice(list, start, finish)
return new_list
end
--- Efficiently insert items into the middle of a list.
---
--- Calling table.insert() in a loop will re-index the tail of the table on
--- every iteration, instead this function will re-index the table exactly
--- once.
---
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
---
---@param t any[]
---@param first integer
---@param last integer
---@param v any
function vim._list_insert(t, first, last, v)
local n = #t
-- Shift table forward
for i = n - first, 0, -1 do
t[last + 1 + i] = t[first + i]
end
-- Fill in new values
for i = first, last do
t[i] = v
end
end
--- Efficiently remove items from middle of a list.
---
--- Calling table.remove() in a loop will re-index the tail of the table on
--- every iteration, instead this function will re-index the table exactly
--- once.
---
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
---
---@param t any[]
---@param first integer
---@param last integer
function vim._list_remove(t, first, last)
local n = #t
for i = 0, n - first do
t[first + i] = t[last + 1 + i]
t[last + 1 + i] = nil
end
end
--- Trim whitespace (Lua pattern "%s") from both sides of a string.
---
---@see |lua-patterns|
@ -968,7 +1013,7 @@ do
--- best performance.
---
--- @param name string Argument name
--- @param value string Argument value
--- @param value any Argument value
--- @param validator vim.validate.Validator
--- - (`string|string[]`): Any value that can be returned from |lua-type()| in addition to
--- `'callable'`: `'boolean'`, `'callable'`, `'function'`, `'nil'`, `'number'`, `'string'`, `'table'`,
@ -1354,4 +1399,24 @@ function vim._with(context, f)
return vim._with_c(context, callback)
end
--- @param bufnr? integer
--- @return integer
function vim._resolve_bufnr(bufnr)
if bufnr == nil or bufnr == 0 then
return vim.api.nvim_get_current_buf()
end
vim.validate('bufnr', bufnr, 'number')
return bufnr
end
--- @generic T
--- @param x elem_or_list<T>?
--- @return T[]
function vim._ensure_list(x)
if type(x) == 'table' then
return x
end
return { x }
end
return vim

View File

@ -2,6 +2,18 @@
local M = {}
local alphabet = '0123456789ABCDEF'
local atoi = {} ---@type table<string, integer>
local itoa = {} ---@type table<integer, string>
do
for i = 1, #alphabet do
local char = alphabet:sub(i, i)
itoa[i - 1] = char
atoi[char] = i - 1
atoi[char:lower()] = i - 1
end
end
--- Hex encode a string.
---
--- @param str string String to encode
@ -9,7 +21,9 @@ local M = {}
function M.hexencode(str)
local enc = {} ---@type string[]
for i = 1, #str do
enc[i] = string.format('%02X', str:byte(i, i + 1))
local byte = str:byte(i)
enc[2 * i - 1] = itoa[math.floor(byte / 16)]
enc[2 * i] = itoa[byte % 16]
end
return table.concat(enc)
end
@ -26,8 +40,12 @@ function M.hexdecode(enc)
local str = {} ---@type string[]
for i = 1, #enc, 2 do
local n = assert(tonumber(enc:sub(i, i + 1), 16))
str[#str + 1] = string.char(n)
local u = atoi[enc:sub(i, i)]
local l = atoi[enc:sub(i + 1, i + 1)]
if not u or not l then
return nil, 'string must contain only hex characters'
end
str[(i + 1) / 2] = string.char(u * 16 + l)
end
return table.concat(str), nil
end

View File

@ -32,9 +32,7 @@ M.minimum_language_version = vim._ts_get_minimum_language_version()
---
---@return vim.treesitter.LanguageTree object to use for parsing
function M._create_parser(bufnr, lang, opts)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
vim.fn.bufload(bufnr)
@ -90,9 +88,7 @@ function M.get_parser(bufnr, lang, opts)
opts = opts or {}
local should_error = opts.error == nil or opts.error
if bufnr == nil or bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
if not valid_lang(lang) then
lang = M.language.get_lang(vim.bo[bufnr].filetype)
@ -249,18 +245,17 @@ end
--- Returns a list of highlight captures at the given position
---
--- Each capture is represented by a table containing the capture name as a string as
--- well as a table of metadata (`priority`, `conceal`, ...; empty if none are defined).
--- Each capture is represented by a table containing the capture name as a string, the capture's
--- language, a table of metadata (`priority`, `conceal`, ...; empty if none are defined), and the
--- id of the capture.
---
---@param bufnr integer Buffer number (0 for current buffer)
---@param row integer Position row
---@param col integer Position column
---
---@return {capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata}[]
---@return {capture: string, lang: string, metadata: vim.treesitter.query.TSMetadata, id: integer}[]
function M.get_captures_at_pos(bufnr, row, col)
if bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
bufnr = vim._resolve_bufnr(bufnr)
local buf_highlighter = M.highlighter.active[bufnr]
if not buf_highlighter then
@ -291,12 +286,15 @@ function M.get_captures_at_pos(bufnr, row, col)
local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1)
for capture, node, metadata in iter do
for id, node, metadata in iter do
if M.is_in_node_range(node, row, col) then
---@diagnostic disable-next-line: invisible
local c = q._query.captures[capture] -- name of the capture in the query
if c ~= nil then
table.insert(matches, { capture = c, metadata = metadata, lang = tree:lang() })
local capture = q._query.captures[id] -- name of the capture in the query
if capture ~= nil then
table.insert(
matches,
{ capture = capture, metadata = metadata, lang = tree:lang(), id = id }
)
end
end
end
@ -361,11 +359,7 @@ end
function M.get_node(opts)
opts = opts or {}
local bufnr = opts.bufnr
if not bufnr or bufnr == 0 then
bufnr = api.nvim_get_current_buf()
end
local bufnr = vim._resolve_bufnr(opts.bufnr)
local row, col --- @type integer, integer
if opts.pos then
@ -417,7 +411,7 @@ end
---@param bufnr (integer|nil) Buffer to be highlighted (default: current buffer)
---@param lang (string|nil) Language of the parser (default: from buffer filetype)
function M.start(bufnr, lang)
bufnr = bufnr or api.nvim_get_current_buf()
bufnr = vim._resolve_bufnr(bufnr)
local parser = assert(M.get_parser(bufnr, lang, { error = false }))
M.highlighter.new(parser)
end
@ -426,7 +420,7 @@ end
---
---@param bufnr (integer|nil) Buffer to stop highlighting (default: current buffer)
function M.stop(bufnr)
bufnr = (bufnr and bufnr ~= 0) and bufnr or api.nvim_get_current_buf()
bufnr = vim._resolve_bufnr(bufnr)
if M.highlighter.active[bufnr] then
M.highlighter.active[bufnr]:destroy()

Some files were not shown because too many files have changed in this diff Show More