mirror of
https://github.com/neovim/neovim.git
synced 2026-08-28 01:51:52 +00:00
feat(options): schema, "dict" options, messages
Problem:
Options parsing is still painful for dict-style options.
Solution:
schema-maxxing => better `opt:get()` (will be the basis for `vim.o()`),
unified (and more-detailed) err msgs.
- Drop bespoke structure-builder in `_core/options.lua`.
- Define `schema` for all non-primitive options (except 'guicursor' and
statusline-style options); generate reified keysets `OptKeyDict`).
- Generate 'fillchars' => `fcs_tab`, 'listchars' => `lcs_tab`.
- `nvim_set_option_value`:
- Return the improved structures. Also from `vim.opt.x:get()`.
- Eliminate api <=> lua roundtrip, centralize option structure
handling.
- Improve/unify errors.
- Bump ERR_BUFLEN 80 → 256 so the "one of" list isn't truncated.
- Eliminate old 'diffopt' order-dependence (`iwhiteall` before `iwhite`)
Error samples:
Typed-key path (opt_strings_check → diffopt/mousescroll/breakindentopt):
E474: Unknown item 'foo'
E474: 'context' requires a number
E474: 'ver' number is out of range
E474: 'algorithm' must be one of: myers, minimal, patience, histogram
E474: 'filler' does not take a value
Related:
- #31084
- #34661
- #31820
- #14739
- #20107
- fix #18875
- :get() returns `{ sbr = true, shift = '3' }` (reified-keyset) instead of `{'sbr', 'shift:3'}`
- Setting via table now works too. `object_as_optval_for` `is_map` now recognizes struct options.
- fix #30296
- instead of `E474: Invalid argument`, errors now look like:
```
E474: Invalid value 'x', expected one of: single, double: ambiwidth=x
E474: Unknown item 'foo': diffopt=foo
E474: 'context' requires a number: diffopt=context:x
```
simplify `win_float_parse_option` from #26799.
This commit is contained in:
@@ -897,6 +897,37 @@ describe('lua stdlib', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
it("returns structured values for a dict option ('diffopt')", function()
|
||||
-- Bare flags -> true; sub-values stay strings (option sub-value types are not exposed).
|
||||
eq_exec_lua({ internal = true, filler = true, context = '4' }, function()
|
||||
vim.opt.diffopt = 'internal,filler,context:4'
|
||||
return vim.opt.diffopt:get()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('roundtrips a dict option through :set', function()
|
||||
eq_exec_lua('context:4,filler,internal', function()
|
||||
vim.opt.diffopt = 'internal,filler,context:4'
|
||||
vim.opt.diffopt = vim.opt.diffopt:get()
|
||||
return vim.go.diffopt
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Dict option accepts a table and :get() returns a map. #18875
|
||||
it("roundtrips a window-local dict option ('breakindentopt')", function()
|
||||
eq_exec_lua({ sbr = true, shift = '3' }, function()
|
||||
vim.opt.breakindentopt = { sbr = true, shift = 3 }
|
||||
return vim.opt.breakindentopt:get()
|
||||
end)
|
||||
end)
|
||||
|
||||
it("roundtrips a table for 'mousescroll'", function()
|
||||
eq_exec_lua({ hor = '6', ver = '3' }, function()
|
||||
vim.opt.mousescroll = { hor = 6, ver = 3 }
|
||||
return vim.opt.mousescroll:get()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('works for key-value pair options', function()
|
||||
eq_exec_lua({ tab = '> ', space = '_' }, function()
|
||||
vim.opt.listchars = 'tab:> ,space:_'
|
||||
@@ -1249,17 +1280,17 @@ describe('lua stdlib', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
-- isfname=a,b,c,,,d,e,f
|
||||
-- The raw string keeps the ",," literal-comma convention; the structured view splits on every
|
||||
-- comma and does not reconstruct literal commas.
|
||||
it('can handle isfname ,,,', function()
|
||||
eq_exec_lua({ { ',', 'a', 'b', 'c' }, 'a,b,,,c' }, function()
|
||||
eq_exec_lua({ { 'a', 'b', 'c' }, 'a,b,,,c' }, function()
|
||||
vim.opt.isfname = 'a,b,,,c'
|
||||
return { vim.opt.isfname:get(), vim.go.isfname }
|
||||
end)
|
||||
end)
|
||||
|
||||
-- isfname=a,b,c,^,,def
|
||||
it('can handle isfname ,^,,', function()
|
||||
eq_exec_lua({ { '^,', 'a', 'b', 'c' }, 'a,b,^,,c' }, function()
|
||||
eq_exec_lua({ { 'a', 'b', '^', 'c' }, 'a,b,^,,c' }, function()
|
||||
vim.opt.isfname = 'a,b,^,,c'
|
||||
return { vim.opt.isfname:get(), vim.go.isfname }
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user