Commit Graph
54 Commits
Author SHA1 Message Date
Lewis Russell c6535538f8 fix(lua): enable param-type-mismatch diagnostic
Problem: Argument type mismatches are excluded from EmmyLua checks.

Solution: Correct runtime annotations and calls, document local checker
workarounds, and enable the diagnostic.

AI-assisted
2026-09-28 14:43:14 +01:00
Lewis Russell ffa782066c fix(lua): enable assignment type checking in runtime code
Enable EmmyLua's assign-type-mismatch diagnostic after correcting the
runtime annotations and assignments it flags.

Correct option, tuple, and return types, and use separate locals when a
value changes representation. Add guards and narrow casts where needed
so the runtime passes the stricter check. Regenerate the affected docs.

AI-assisted
2026-09-25 17:07:21 +01:00
Lewis Russell d7af870702 fix(lua): enable nil-safety diagnostics in runtime code
Enable EmmyLua's need-check-nil diagnostic and resolve nullable values
through more precise types, explicit invariants, and guards for missing
runtime state. Keep analyzer-specific workarounds local and update the
affected API documentation.

Exclude the bundled re.lua from analysis so its nil-check warnings do
not fail CI.

AI-assisted
2026-09-25 10:28:19 +01:00
Lewis Russell c171a697cb fix(lua): add missing param annotations (#41911) 2026-09-15 14:14:21 +01:00
Volodymyr Chernetskyi ac36bab805 fix(loader): use the statistic name when printing its heading #41887
Problem:
Printing loader statistics concatenates the statistics table into the
heading, raising an error before displaying the results.

Solution:
Use the iteration key for the heading. Cover printing loader statistics.

AI-assisted
2026-09-12 18:50:30 -04:00
Lewis Russell d039f19af5 build: enable more EmmyLua checks
Enable checks for unused code, deprecated calls, return types, and
annotations.

Fix the warnings and replace the deprecated highlight function. Keep
exceptions where old APIs are still needed or the checker gets it wrong.

AI-assisted
2026-09-09 22:31:58 +01:00
Lewis Russell 65ef6fdaee build: replace LuaLS with EmmyLua
Problem: LuaLS struggles with the generics used in Nvim's runtime,
requiring broad diagnostic suppressions. Indexing is also slow.

Solution: Use EmmyLua for type checks in the build and CI. It offers
more sophisticated type checking, substantially better support for
generics, and much better flow analysis.

Correct the affected annotations. Use `@internal`, supported directly by
EmmyLua, instead of `@nodoc` for shared internal declarations, and
support it in the help parser.

AI-assisted
2026-09-07 15:33:22 +01:00
Volodymyr Chernetskyi 5bc7dbb13e fix(loader): remove all cached loaders on disable #41613
Problem:
When disabling, the loader list is traversed forwards while entries are
removed. As a result, some entries are skipped and remain active. Thus,
disabling `vim.loader` restores `_G.loadfile`, but does not fully
restore the original package loader chain.

Solution:
Traverse `package.loaders` in reverse when removing cached loaders.
Capture the original `package.loaders` list in the test, and assert that
the list is restored properly.
2026-09-02 10:08:37 -04:00
Olivia Kinnear 6107629c5b feat(fs): vim.fs.normalize{plain:boolean} #41127
`opts.plain=true` does not expand tildes in addition to environment
variables, unlike `opts.expand_env=false`.

`opts.expand_env=false` is soft-deprecated.
2026-08-05 16:11:13 -04:00
Justin M. Keyes 9982f6e0e4 refactor(api): omit optional param 2026-07-13 19:44:15 +02:00
Yi Ming fd51fb3fa0 refactor!: remove deprecated APIs 2026-05-11 16:51:58 +08:00
Lewis Russell ce1154048b refactor: integer functions, optimize asserts #34112
refactor(lua): add integer coercion helpers

Add vim._tointeger() and vim._ensure_integer(), including optional base
support, and switch integer-only tonumber()/assert call sites in the Lua
runtime to use them.

This also cleans up related integer parsing in LSP, health, loader, URI,
tohtml, and Treesitter code.

supported by AI
2026-03-12 11:04:05 -04:00
Yochem van Rosmalen f7041625f1 refactor(lua): use vim.fs instead of fnamemodify
Although powerful -- especially with chained modifiers --, the
readability (and therefore maintainability) of `fnamemodify()` and its
modifiers is often worse than a function name, giving less context and
having to rely on `:h filename-modifiers`. However, it is used plenty in
the Lua stdlib:

- 16x for the basename: `fnamemodify(path, ':t')`
- 7x for the parents: `fnamemodify(path, ':h')`
- 7x for the stem (filename w/o extension): `fnamemodify(path, ':r')`
- 6x for the absolute path: `fnamemodify(path, ':p')`
- 2x for the suffix: `fnamemodify(path, ':e')`
- 2x relative to the home directory: `fnamemodify(path, ':~')`
- 1x relative to the cwd: `fnamemodify(path, ':.')`

The `fs` module in the stdlib provides a cleaner interface for most of
these path operations: `vim.fs.basename` instead of `':t'`,
`vim.fs.dirname` instead of `':h'`, `vim.fs.abspath` instead of `':p'`.
This commit refactors the runtime to use these instead of fnamemodify.

Not all fnamemodify calls are removed; some have intrinsic differences
in behavior with the `vim.fs` replacement or do not yet have a
replacement in the Lua module, i.e. `:~`, `:.`, `:e` and `:r`.
2026-01-28 10:57:39 +00:00
zeertzjq c08139d790 fix(lua): don't remove first char of non-file stacktrace source (#37008) 2025-12-18 08:09:16 +08:00
Shmerl 1363ef7d50 fix(vim.loader): randomized AppImage path pollutes luac cache #36944
different approach to 78bbe53f76
2025-12-14 13:46:53 -05:00
Shmerl 78bbe53f76 fix(vim.loader): randomized AppImage path pollutes luac cache #35636
Problem:
When using the Nvim appimage, `~/.cache/nvim/luac` directory can grow to
250,000+ files.

Example of 2 identical files in `./luac/`:

    %2ftmp%2f.mount_nvim.a65Rja0%2fusr%2fshare%2fnvim%2fruntime%2flua%2fvim%2ftreesitter.luac
    %2ftmp%2f.mount_nvim.aNpxXgo%2fusr%2fshare%2fnvim%2fruntime%2flua%2fvim%2ftreesitter.luac

Analysis:
The `nvim.appimage` mounts nvim at a different temporary path each time
it is invoked. The naming scheme of these cache files is random, which
defats the purpose of the cache creates N new files on every launch of
nvim.

Steps to reproduce:
1. install `nvim.appimage`
2. `mv ~/.cache/nvim/luac ~/.cache/nvim/luac.backup`
3. `nvim`
4. Observe contents of `~/.cache/nvim/luac/`
5. Close nvim and run `nvim` again
6. Observe contents of `~/.cache/nvim/luac/` and see that new identical
   files have been added with a different mount prefix

Solution:
When running from an appimage, trim the random part of the filepaths.
2025-12-10 13:33:33 -05:00
Christian Clason c10e36fc01 refactor(lua): consistent use of local aliases 2025-08-28 11:34:01 +02:00
Lewis Russell 3b6084ddf4 fix: type fixes
Type fixes caught by emmylua
2025-06-06 15:36:48 +01: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
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
Lewis Russell be04bbf781 refactor(loader): format annotations 2024-10-31 15:20:29 +00:00
Lewis Russell 086e598a6e refactor(loader): use the term stat instead of hash 2024-10-31 15:20:29 +00:00
Lewis Russell 8d68d883a9 refactor(loader): remove Loader table and use locals 2024-10-31 15:20:29 +00:00
Lewis Russell 4a0010e267 refactor(loader): rename types 2024-10-31 15:20:29 +00:00
Lewis Russell 7ccdd9235a refactor(loader): inline Loader.load into Loader.loadfile 2024-10-31 15:20:29 +00:00
Lewis Russell ab2f2461b5 refactor(loader): simplify Loader.loader_lib 2024-10-31 15:20:27 +00:00
Lewis Russell 53536be62a refactor(loader): simplify Loader.write/read 2024-10-31 15:02:12 +00:00
Lewis Russell f8fc6cb157 perf(loader): reduce calls to Loader.cache_file 2024-10-31 15:02:08 +00:00
Lewis Russell 03118c46ab refactor(loader): remove unused _topmods 2024-10-31 14:15:09 +00:00
Justin M. Keyes b45c50f314 docs: render @since versions, 0 means experimental #30649
An implication of this current approach is that `NVIM_API_LEVEL` should be
bumped when a new Lua function is added.

TODO(future): add a lint check which requires `@since` on all new functions.

ref #25416
2024-10-04 02:13:31 -07:00
Justin M. Keyes 47e6b2233f fix(vim.fs): dirname() returns "." on mingw/msys2 #30480
Problem:
`vim.fs.dirname([[C:\User\XXX\AppData\Local]])` returns "." on
mingw/msys2.

Solution:
- Check for "mingw" when deciding `iswin`.
- Use `has("win32")` where possible, it works in "fast" contexts since
  b02eeb6a72.
2024-09-23 06:05:58 -07:00
futsuuu 67bb0cfa79 fix(loader): follow the style of the error message for built-in loaders
start the error message with '\n\t' instead of '\n'
surround the module name by single quotes
2024-08-13 14:05:10 +01:00
Lewis Russell dcdefd0428 perf(loader): use a quicker version of vim.fs.normalize
Problem:

vim.fs.normalize() normalizes too much vim.loader and is slow.

Solution:

Make it faster by doing less. This reduces the times spent in
vim.fs.normalize in vim.loader from ~13ms -> 1-2ms.

Numbers from a relative benchmark:
- Skipping `vim.validate()`: 285ms -> 230ms
- Skipping `path_resolve_dot()`: 285ms -> 60ms
- Skipping `double_slash`: 60ms -> 35ms
2024-05-15 12:38:26 +01:00
Lewis Russell ea44f74d84 refactor(types): more fixes 2024-03-06 10:45:22 +00:00
Lewis Russell a5fe8f59d9 docs: improve/add documentation of Lua types
- Added `@inlinedoc` so single use Lua types can be inlined into the
  functions docs. E.g.

  ```lua
  --- @class myopts
  --- @inlinedoc
  ---
  --- Documentation for some field
  --- @field somefield integer

  --- @param opts myOpts
  function foo(opts)
  end
  ```

  Will be rendered as

  ```
  foo(opts)

    Parameters:
      - {opts} (table) Object with the fields:
               - somefield (integer) Documentation
                 for some field
  ```

- Marked many classes with with `@nodoc` or `(private)`.
  We can eventually introduce these when we want to.
2024-03-01 23:02:18 +00:00
Lewis Russell 9beb40a4db feat(docs): replace lua2dox.lua
Problem:

The documentation flow (`gen_vimdoc.py`) has several issues:
- it's not very versatile
- depends on doxygen
- doesn't work well with Lua code as it requires an awkward filter script to convert it into pseudo-C.
- The intermediate XML files and filters makes it too much like a rube goldberg machine.

Solution:

Re-implement the flow using Lua, LPEG and treesitter.

- `gen_vimdoc.py` is now replaced with `gen_vimdoc.lua` and replicates a portion of the logic.
- `lua2dox.lua` is gone!
- No more XML files.
- Doxygen is now longer used and instead we now use:
  - LPEG for comment parsing (see `scripts/luacats_grammar.lua` and `scripts/cdoc_grammar.lua`).
  - LPEG for C parsing (see `scripts/cdoc_parser.lua`)
  - Lua patterns for Lua parsing (see `scripts/luacats_parser.lua`).
  - Treesitter for Markdown parsing (see `scripts/text_utils.lua`).
- The generated `runtime/doc/*.mpack` files have been removed.
   - `scripts/gen_eval_files.lua` now instead uses `scripts/cdoc_parser.lua` directly.
- Text wrapping is implemented in `scripts/text_utils.lua` and appears to produce more consistent results (the main contributer to the diff of this change).
2024-02-27 14:41:17 +00:00
Jongwook Choi 89135cff03 fix(loader): remove cyclic dependency on vim.fs (when --luamod-dev)
Problem: Loading `vim.fs` via the `vim.loader` Lua package loader will
result in a stack overflow due to a cyclic dependency. This may happen
when the `vim.fs` module isn't byte-compiled, i.e. when `--luamod-dev`
is used (#27413).

Solution: `vim.loader` depends on `vim.fs`. Therefore `vim.fs` should
be loaded in advance.
2024-02-13 10:29:22 +00:00
dundargoc d51b615747 refactor: fix luals warnings 2023-12-30 17:40:53 +01:00
Christian Clason c43c745a14 fix(lua): improve annotations for stricter luals diagnostics (#24609)
Problem: luals returns stricter diagnostics with bundled luarc.json
Solution: Improve some function and type annotations:

* use recognized uv.* types 
* disable diagnostic for global `vim` in shared.lua
* docs: don't start comment lines with taglink (otherwise LuaLS will interpret it as a type)
* add type alias for lpeg pattern
* fix return annotation for `vim.secure.trust`
* rename local Range object in vim.version (shadows `Range` in vim.treesitter)
* fix some "missing fields" warnings
* add missing required fields for test functions in eval.lua
* rename lsp meta files for consistency
2023-08-09 11:06:13 +02:00
Tyler Miller 0804034c07 fix(loader): cache path ambiguity #24491
Problem: cache paths are derived by replacing each reserved/filesystem-
path-sensitive char with a `%` char in the original path. With this
method, two different files at two different paths (each containing `%`
chars) can erroneously resolve to the very same cache path in certain
edge-cases.

Solution: derive cache paths by url-encoding the original (path) instead
using `vim.uri_encode()` with `"rfc2396"`. Increment `Loader.VERSION` to
denote this change.
2023-08-01 08:28:28 -07:00
Lewis RussellandJustin M. Keyes be74807eef docs(lua): more improvements (#24387)
* docs(lua): teach lua2dox how to table

* docs(lua): teach gen_vimdoc.py about local functions

No more need to mark local functions with @private

* docs(lua): mention @nodoc and @meta in dev-lua-doc

* fixup!

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>

---------

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2023-07-18 15:42:30 +01:00
Justin M. Keyes 4e6356559c test: spellcheck :help (vimdoc) files #24109
Enforce consistent terminology (defined in
`gen_help_html.lua:spell_dict`) for common misspellings.

This does not spellcheck English in general (perhaps a future TODO,
though it may be noisy).
2023-06-22 03:44:51 -07:00
Lewis Russell 2db719f6c2 feat(lua): rename vim.loop -> vim.uv (#22846) 2023-06-03 12:06:00 +02:00
Christian Clason 4d04feb662 feat(lua): vim.tbl_contains supports general tables and predicates (#23040)
* feat(lua): vim.tbl_contains supports general tables and predicates

Problem: `vim.tbl_contains` only works for list-like tables (integer
keys without gaps) and primitive values (in particular, not for nested
tables).

Solution: Rename `vim.tbl_contains` to `vim.list_contains` and add new
`vim.tbl_contains` that works for general tables and optionally allows
`value` to be a predicate function that is checked for every key.
2023-04-14 10:39:57 +02:00
Lewis Russell 66c66d8db8 fix(loader): reset hashes when running the loader 2023-04-13 17:34:47 +01:00
a5c572bd44 docs: fix typos
Co-authored-by: Gregory Anders <greg@gpanders.com>
Co-authored-by: Raphael <glephunter@gmail.com>
Co-authored-by: C.D. MacEachern <craig.daniel.maceachern@gmail.com>
Co-authored-by: himanoa <matsunoappy@gmail.com>
2023-04-04 19:07:33 +02:00
Lewis Russell 83bfd94d1d refactor(loader): cache hash information
Whenever we run fs_stat() on a path, save this information in the loader
so it can be re-used.

- Loader.loadfile: Remove arguments `hash` as it is no longer needed.

- Loader.loader: Use _G.loadstring instead of Loader.load
  This allows plugins to wrap loadstring to inspection and profiling

- factor out read file logic
2023-03-31 13:05:22 +01:00
Lewis Russell 4cff3aceea fix(loader): disable profiling by default 2023-03-31 09:43:13 +01:00
Lewis Russell fd70a9dca1 refactor(loader): simplify tracking logic 2023-03-26 14:11:43 +01:00
Lewis Russell 25fa051fa1 feat(vim.fs): improve normalize
- Add options argument with an option to expand env vars
- Resolve '//' -> '/'
- Use in vim.loader
2023-03-26 13:30:11 +01:00