_options.lua 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. --- @brief Nvim Lua provides an interface or "bridge" to Vimscript variables and
  2. --- functions, and editor commands and options.
  3. ---
  4. --- Objects passed over this bridge are COPIED (marshalled): there are no
  5. --- "references". |lua-guide-variables| For example, using `vim.fn.remove()` on
  6. --- a Lua list copies the list object to Vimscript and does NOT modify the Lua
  7. --- list:
  8. ---
  9. --- ```lua
  10. --- local list = { 1, 2, 3 }
  11. --- vim.fn.remove(list, 0)
  12. --- vim.print(list) --> "{ 1, 2, 3 }"
  13. --- ```
  14. --- @brief <pre>help
  15. --- vim.call({func}, {...}) *vim.call()*
  16. --- Invokes |vim-function| or |user-function| {func} with arguments {...}.
  17. --- See also |vim.fn|.
  18. --- Equivalent to: >lua
  19. --- vim.fn[func]({...})
  20. --- <
  21. --- vim.cmd({command})
  22. --- See |vim.cmd()|.
  23. ---
  24. --- vim.fn.{func}({...}) *vim.fn*
  25. --- Invokes |vim-function| or |user-function| {func} with arguments {...}.
  26. --- To call autoload functions, use the syntax: >lua
  27. --- vim.fn['some#function']({...})
  28. --- <
  29. --- Unlike vim.api.|nvim_call_function()| this converts directly between Vim
  30. --- objects and Lua objects. If the Vim function returns a float, it will be
  31. --- represented directly as a Lua number. Empty lists and dictionaries both
  32. --- are represented by an empty table.
  33. ---
  34. --- Note: |v:null| values as part of the return value is represented as
  35. --- |vim.NIL| special value
  36. ---
  37. --- Note: vim.fn keys are generated lazily, thus `pairs(vim.fn)` only
  38. --- enumerates functions that were called at least once.
  39. ---
  40. --- Note: The majority of functions cannot run in |api-fast| callbacks with some
  41. --- undocumented exceptions which are allowed.
  42. ---
  43. --- *lua-vim-variables*
  44. --- The Vim editor global dictionaries |g:| |w:| |b:| |t:| |v:| can be accessed
  45. --- from Lua conveniently and idiomatically by referencing the `vim.*` Lua tables
  46. --- described below. In this way you can easily read and modify global Vimscript
  47. --- variables from Lua.
  48. ---
  49. --- Example: >lua
  50. ---
  51. --- vim.g.foo = 5 -- Set the g:foo Vimscript variable.
  52. --- print(vim.g.foo) -- Get and print the g:foo Vimscript variable.
  53. --- vim.g.foo = nil -- Delete (:unlet) the Vimscript variable.
  54. --- vim.b[2].foo = 6 -- Set b:foo for buffer 2
  55. --- <
  56. ---
  57. --- Note that setting dictionary fields directly will not write them back into
  58. --- Nvim. This is because the index into the namespace simply returns a copy.
  59. --- Instead the whole dictionary must be written as one. This can be achieved by
  60. --- creating a short-lived temporary.
  61. ---
  62. --- Example: >lua
  63. ---
  64. --- vim.g.my_dict.field1 = 'value' -- Does not work
  65. ---
  66. --- local my_dict = vim.g.my_dict --
  67. --- my_dict.field1 = 'value' -- Instead do
  68. --- vim.g.my_dict = my_dict --
  69. ---
  70. --- vim.g *vim.g*
  71. --- Global (|g:|) editor variables.
  72. --- Key with no value returns `nil`.
  73. ---
  74. --- vim.b *vim.b*
  75. --- Buffer-scoped (|b:|) variables for the current buffer.
  76. --- Invalid or unset key returns `nil`. Can be indexed with
  77. --- an integer to access variables for a specific buffer.
  78. ---
  79. --- vim.w *vim.w*
  80. --- Window-scoped (|w:|) variables for the current window.
  81. --- Invalid or unset key returns `nil`. Can be indexed with
  82. --- an integer to access variables for a specific window.
  83. ---
  84. --- vim.t *vim.t*
  85. --- Tabpage-scoped (|t:|) variables for the current tabpage.
  86. --- Invalid or unset key returns `nil`. Can be indexed with
  87. --- an integer to access variables for a specific tabpage.
  88. ---
  89. --- vim.v *vim.v*
  90. --- |v:| variables.
  91. --- Invalid or unset key returns `nil`.
  92. --- </pre>
  93. local api = vim.api
  94. -- TODO(tjdevries): Improve option metadata so that this doesn't have to be hardcoded.
  95. local key_value_options = {
  96. fillchars = true,
  97. fcs = true,
  98. listchars = true,
  99. lcs = true,
  100. winhighlight = true,
  101. winhl = true,
  102. }
  103. --- @nodoc
  104. --- @class vim._option.Info : vim.api.keyset.get_option_info
  105. --- @field metatype 'boolean'|'string'|'number'|'map'|'array'|'set'
  106. --- Convert a vimoption_T style dictionary to the correct OptionType associated with it.
  107. ---@return string
  108. local function get_option_metatype(name, info)
  109. if info.type == 'string' then
  110. if info.flaglist then
  111. return 'set'
  112. elseif info.commalist then
  113. if key_value_options[name] then
  114. return 'map'
  115. end
  116. return 'array'
  117. end
  118. return 'string'
  119. end
  120. return info.type
  121. end
  122. --- @param name string
  123. --- @return vim._option.Info
  124. local function get_options_info(name)
  125. local info = api.nvim_get_option_info2(name, {})
  126. --- @cast info vim._option.Info
  127. info.metatype = get_option_metatype(name, info)
  128. return info
  129. end
  130. --- Environment variables defined in the editor session.
  131. --- See |expand-env| and |:let-environment| for the Vimscript behavior.
  132. --- Invalid or unset key returns `nil`.
  133. ---
  134. --- Example:
  135. ---
  136. --- ```lua
  137. --- vim.env.FOO = 'bar'
  138. --- print(vim.env.TERM)
  139. --- ```
  140. vim.env = setmetatable({}, {
  141. __index = function(_, k)
  142. local v = vim.fn.getenv(k)
  143. if v == vim.NIL then
  144. return nil
  145. end
  146. return v
  147. end,
  148. __newindex = function(_, k, v)
  149. vim.fn.setenv(k, v)
  150. end,
  151. })
  152. local function new_buf_opt_accessor(bufnr)
  153. return setmetatable({}, {
  154. __index = function(_, k)
  155. if bufnr == nil and type(k) == 'number' then
  156. return new_buf_opt_accessor(k)
  157. end
  158. return api.nvim_get_option_value(k, { buf = bufnr or 0 })
  159. end,
  160. __newindex = function(_, k, v)
  161. return api.nvim_set_option_value(k, v, { buf = bufnr or 0 })
  162. end,
  163. })
  164. end
  165. local function new_win_opt_accessor(winid, bufnr)
  166. -- TODO(lewis6991): allow passing both buf and win to nvim_get_option_value
  167. if bufnr ~= nil and bufnr ~= 0 then
  168. error('only bufnr=0 is supported')
  169. end
  170. return setmetatable({}, {
  171. __index = function(_, k)
  172. if bufnr == nil and type(k) == 'number' then
  173. if winid == nil then
  174. return new_win_opt_accessor(k)
  175. else
  176. return new_win_opt_accessor(winid, k)
  177. end
  178. end
  179. return api.nvim_get_option_value(k, {
  180. scope = bufnr and 'local' or nil,
  181. win = winid or 0,
  182. })
  183. end,
  184. __newindex = function(_, k, v)
  185. return api.nvim_set_option_value(k, v, {
  186. scope = bufnr and 'local' or nil,
  187. win = winid or 0,
  188. })
  189. end,
  190. })
  191. end
  192. --- @brief <pre>help
  193. --- *lua-options*
  194. --- *lua-vim-options*
  195. --- *lua-vim-set*
  196. --- *lua-vim-setlocal*
  197. ---
  198. --- Vim options can be accessed through |vim.o|, which behaves like Vimscript
  199. --- |:set|.
  200. ---
  201. --- Examples: ~
  202. ---
  203. --- To set a boolean toggle:
  204. --- Vimscript: `set number`
  205. --- Lua: `vim.o.number = true`
  206. ---
  207. --- To set a string value:
  208. --- Vimscript: `set wildignore=*.o,*.a,__pycache__`
  209. --- Lua: `vim.o.wildignore = '*.o,*.a,__pycache__'`
  210. ---
  211. --- Similarly, there is |vim.bo| and |vim.wo| for setting buffer-scoped and
  212. --- window-scoped options. Note that this must NOT be confused with
  213. --- |local-options| and |:setlocal|. There is also |vim.go| that only accesses the
  214. --- global value of a |global-local| option, see |:setglobal|.
  215. --- </pre>
  216. --- Get or set |options|. Like `:set`. Invalid key is an error.
  217. ---
  218. --- Note: this works on both buffer-scoped and window-scoped options using the
  219. --- current buffer and window.
  220. ---
  221. --- Example:
  222. ---
  223. --- ```lua
  224. --- vim.o.cmdheight = 4
  225. --- print(vim.o.columns)
  226. --- print(vim.o.foo) -- error: invalid key
  227. --- ```
  228. vim.o = setmetatable({}, {
  229. __index = function(_, k)
  230. return api.nvim_get_option_value(k, {})
  231. end,
  232. __newindex = function(_, k, v)
  233. return api.nvim_set_option_value(k, v, {})
  234. end,
  235. })
  236. --- Get or set global |options|. Like `:setglobal`. Invalid key is
  237. --- an error.
  238. ---
  239. --- Note: this is different from |vim.o| because this accesses the global
  240. --- option value and thus is mostly useful for use with |global-local|
  241. --- options.
  242. ---
  243. --- Example:
  244. ---
  245. --- ```lua
  246. --- vim.go.cmdheight = 4
  247. --- print(vim.go.columns)
  248. --- print(vim.go.bar) -- error: invalid key
  249. --- ```
  250. vim.go = setmetatable({}, {
  251. __index = function(_, k)
  252. return api.nvim_get_option_value(k, { scope = 'global' })
  253. end,
  254. __newindex = function(_, k, v)
  255. return api.nvim_set_option_value(k, v, { scope = 'global' })
  256. end,
  257. })
  258. --- Get or set buffer-scoped |options| for the buffer with number {bufnr}.
  259. --- Like `:setlocal`. If {bufnr} is omitted then the current buffer is used.
  260. --- Invalid {bufnr} or key is an error.
  261. ---
  262. --- Example:
  263. ---
  264. --- ```lua
  265. --- local bufnr = vim.api.nvim_get_current_buf()
  266. --- vim.bo[bufnr].buflisted = true -- same as vim.bo.buflisted = true
  267. --- print(vim.bo.comments)
  268. --- print(vim.bo.baz) -- error: invalid key
  269. --- ```
  270. vim.bo = new_buf_opt_accessor()
  271. --- Get or set window-scoped |options| for the window with handle {winid} and
  272. --- buffer with number {bufnr}. Like `:setlocal` if setting a |global-local| option
  273. --- or if {bufnr} is provided, like `:set` otherwise. If {winid} is omitted then
  274. --- the current window is used. Invalid {winid}, {bufnr} or key is an error.
  275. ---
  276. --- Note: only {bufnr} with value `0` (the current buffer in the window) is
  277. --- supported.
  278. ---
  279. --- Example:
  280. ---
  281. --- ```lua
  282. --- local winid = vim.api.nvim_get_current_win()
  283. --- vim.wo[winid].number = true -- same as vim.wo.number = true
  284. --- print(vim.wo.foldmarker)
  285. --- print(vim.wo.quux) -- error: invalid key
  286. --- vim.wo[winid][0].spell = false -- like ':setlocal nospell'
  287. --- ```
  288. vim.wo = new_win_opt_accessor()
  289. --- vim.opt, vim.opt_local and vim.opt_global implementation
  290. ---
  291. --- To be used as helpers for working with options within neovim.
  292. --- For information on how to use, see :help vim.opt
  293. --- Preserves the order and does not mutate the original list
  294. --- @generic T
  295. --- @param t T[]
  296. --- @return T[]
  297. local function remove_duplicate_values(t)
  298. --- @type table, table<any,true>
  299. local result, seen = {}, {}
  300. for _, v in
  301. ipairs(t --[[@as any[] ]])
  302. do
  303. if not seen[v] then
  304. table.insert(result, v)
  305. end
  306. seen[v] = true
  307. end
  308. return result
  309. end
  310. --- Check whether the OptionTypes is allowed for vim.opt
  311. --- If it does not match, throw an error which indicates which option causes the error.
  312. --- @param name any
  313. --- @param value any
  314. --- @param types string[]
  315. local function assert_valid_value(name, value, types)
  316. local type_of_value = type(value)
  317. for _, valid_type in ipairs(types) do
  318. if valid_type == type_of_value then
  319. return
  320. end
  321. end
  322. error(
  323. string.format(
  324. "Invalid option type '%s' for '%s', should be %s",
  325. type_of_value,
  326. name,
  327. table.concat(types, ' or ')
  328. )
  329. )
  330. end
  331. local function passthrough(_, x)
  332. return x
  333. end
  334. local function tbl_merge(left, right)
  335. return vim.tbl_extend('force', left, right)
  336. end
  337. --- @param t table<any,any>
  338. --- @param value any|any[]
  339. local function tbl_remove(t, value)
  340. if type(value) == 'string' then
  341. t[value] = nil
  342. else
  343. for _, v in ipairs(value) do
  344. t[v] = nil
  345. end
  346. end
  347. return t
  348. end
  349. local valid_types = {
  350. boolean = { 'boolean' },
  351. number = { 'number' },
  352. string = { 'string' },
  353. set = { 'string', 'table' },
  354. array = { 'string', 'table' },
  355. map = { 'string', 'table' },
  356. }
  357. -- Map of functions to take a Lua style value and convert to vimoption_T style value.
  358. -- Each function takes (info, lua_value) -> vim_value
  359. local to_vim_value = {
  360. boolean = passthrough,
  361. number = passthrough,
  362. string = passthrough,
  363. --- @param info vim._option.Info
  364. --- @param value string|table<string,true>
  365. set = function(info, value)
  366. if type(value) == 'string' then
  367. return value
  368. end
  369. if info.flaglist and info.commalist then
  370. local keys = {}
  371. for k, v in pairs(value) do
  372. if v then
  373. table.insert(keys, k)
  374. end
  375. end
  376. table.sort(keys)
  377. return table.concat(keys, ',')
  378. else
  379. local result = ''
  380. for k, v in pairs(value) do
  381. if v then
  382. result = result .. k
  383. end
  384. end
  385. return result
  386. end
  387. end,
  388. --- @param info vim._option.Info
  389. --- @param value string|string[]
  390. array = function(info, value)
  391. if type(value) == 'string' then
  392. return value
  393. end
  394. if not info.allows_duplicates then
  395. value = remove_duplicate_values(value)
  396. end
  397. return table.concat(value, ',')
  398. end,
  399. --- @param value string|table<string,string>
  400. map = function(_, value)
  401. if type(value) == 'string' then
  402. return value
  403. end
  404. local result = {}
  405. for opt_key, opt_value in pairs(value) do
  406. table.insert(result, string.format('%s:%s', opt_key, opt_value))
  407. end
  408. table.sort(result)
  409. return table.concat(result, ',')
  410. end,
  411. }
  412. --- Convert a Lua value to a vimoption_T value
  413. local function convert_value_to_vim(name, info, value)
  414. if value == nil then
  415. return vim.NIL
  416. end
  417. assert_valid_value(name, value, valid_types[info.metatype])
  418. return to_vim_value[info.metatype](info, value)
  419. end
  420. -- Map of OptionType to functions that take vimoption_T values and convert to Lua values.
  421. -- Each function takes (info, vim_value) -> lua_value
  422. local to_lua_value = {
  423. boolean = passthrough,
  424. number = passthrough,
  425. string = passthrough,
  426. array = function(info, value)
  427. if type(value) == 'table' then
  428. if not info.allows_duplicates then
  429. value = remove_duplicate_values(value)
  430. end
  431. return value
  432. end
  433. -- Empty strings mean that there is nothing there,
  434. -- so empty table should be returned.
  435. if value == '' then
  436. return {}
  437. end
  438. -- Handles unescaped commas in a list.
  439. if value:find(',,,') then
  440. --- @type string, string
  441. local left, right = unpack(vim.split(value, ',,,'))
  442. local result = {}
  443. vim.list_extend(result, vim.split(left, ','))
  444. table.insert(result, ',')
  445. vim.list_extend(result, vim.split(right, ','))
  446. table.sort(result)
  447. return result
  448. end
  449. if value:find(',^,,', 1, true) then
  450. --- @type string, string
  451. local left, right = unpack(vim.split(value, ',^,,', { plain = true }))
  452. local result = {}
  453. vim.list_extend(result, vim.split(left, ','))
  454. table.insert(result, '^,')
  455. vim.list_extend(result, vim.split(right, ','))
  456. table.sort(result)
  457. return result
  458. end
  459. return vim.split(value, ',')
  460. end,
  461. set = function(info, value)
  462. if type(value) == 'table' then
  463. return value
  464. end
  465. -- Empty strings mean that there is nothing there,
  466. -- so empty table should be returned.
  467. if value == '' then
  468. return {}
  469. end
  470. assert(info.flaglist, 'That is the only one I know how to handle')
  471. local result = {} --- @type table<string,true>
  472. if info.flaglist and info.commalist then
  473. local split_value = vim.split(value, ',')
  474. for _, v in ipairs(split_value) do
  475. result[v] = true
  476. end
  477. else
  478. for i = 1, #value do
  479. result[value:sub(i, i)] = true
  480. end
  481. end
  482. return result
  483. end,
  484. map = function(info, raw_value)
  485. if type(raw_value) == 'table' then
  486. return raw_value
  487. end
  488. assert(info.commalist, 'Only commas are supported currently')
  489. local result = {} --- @type table<string,string>
  490. local comma_split = vim.split(raw_value, ',')
  491. for _, key_value_str in ipairs(comma_split) do
  492. --- @type string, string
  493. local key, value = unpack(vim.split(key_value_str, ':'))
  494. key = vim.trim(key)
  495. result[key] = value
  496. end
  497. return result
  498. end,
  499. }
  500. --- Converts a vimoption_T style value to a Lua value
  501. local function convert_value_to_lua(info, option_value)
  502. return to_lua_value[info.metatype](info, option_value)
  503. end
  504. local prepend_methods = {
  505. number = function()
  506. error("The '^' operator is not currently supported for")
  507. end,
  508. string = function(left, right)
  509. return right .. left
  510. end,
  511. array = function(left, right)
  512. for i = #right, 1, -1 do
  513. table.insert(left, 1, right[i])
  514. end
  515. return left
  516. end,
  517. map = tbl_merge,
  518. set = tbl_merge,
  519. }
  520. --- Handles the '^' operator
  521. local function prepend_value(info, current, new)
  522. return prepend_methods[info.metatype](
  523. convert_value_to_lua(info, current),
  524. convert_value_to_lua(info, new)
  525. )
  526. end
  527. local add_methods = {
  528. --- @param left integer
  529. --- @param right integer
  530. number = function(left, right)
  531. return left + right
  532. end,
  533. --- @param left string
  534. --- @param right string
  535. string = function(left, right)
  536. return left .. right
  537. end,
  538. --- @param left string[]
  539. --- @param right string[]
  540. --- @return string[]
  541. array = function(left, right)
  542. for _, v in ipairs(right) do
  543. table.insert(left, v)
  544. end
  545. return left
  546. end,
  547. map = tbl_merge,
  548. set = tbl_merge,
  549. }
  550. --- Handles the '+' operator
  551. local function add_value(info, current, new)
  552. return add_methods[info.metatype](
  553. convert_value_to_lua(info, current),
  554. convert_value_to_lua(info, new)
  555. )
  556. end
  557. --- @param t table<any,any>
  558. --- @param val any
  559. local function remove_one_item(t, val)
  560. if vim.islist(t) then
  561. local remove_index = nil
  562. for i, v in ipairs(t) do
  563. if v == val then
  564. remove_index = i
  565. end
  566. end
  567. if remove_index then
  568. table.remove(t, remove_index)
  569. end
  570. else
  571. t[val] = nil
  572. end
  573. end
  574. local remove_methods = {
  575. --- @param left integer
  576. --- @param right integer
  577. number = function(left, right)
  578. return left - right
  579. end,
  580. string = function()
  581. error('Subtraction not supported for strings.')
  582. end,
  583. --- @param left string[]
  584. --- @param right string[]
  585. --- @return string[]
  586. array = function(left, right)
  587. if type(right) == 'string' then
  588. remove_one_item(left, right)
  589. else
  590. for _, v in ipairs(right) do
  591. remove_one_item(left, v)
  592. end
  593. end
  594. return left
  595. end,
  596. map = tbl_remove,
  597. set = tbl_remove,
  598. }
  599. --- Handles the '-' operator
  600. local function remove_value(info, current, new)
  601. return remove_methods[info.metatype](convert_value_to_lua(info, current), new)
  602. end
  603. local function create_option_accessor(scope)
  604. local option_mt
  605. local function make_option(name, value)
  606. local info = assert(get_options_info(name), 'Not a valid option name: ' .. name)
  607. if type(value) == 'table' and getmetatable(value) == option_mt then
  608. assert(name == value._name, "must be the same value, otherwise that's weird.")
  609. value = value._value
  610. end
  611. return setmetatable({
  612. _name = name,
  613. _value = value,
  614. _info = info,
  615. }, option_mt)
  616. end
  617. option_mt = {
  618. -- To set a value, instead use:
  619. -- opt[my_option] = value
  620. _set = function(self)
  621. local value = convert_value_to_vim(self._name, self._info, self._value)
  622. api.nvim_set_option_value(self._name, value, { scope = scope })
  623. end,
  624. get = function(self)
  625. return convert_value_to_lua(self._info, self._value)
  626. end,
  627. append = function(self, right)
  628. self._value = add_value(self._info, self._value, right)
  629. self:_set()
  630. end,
  631. __add = function(self, right)
  632. return make_option(self._name, add_value(self._info, self._value, right))
  633. end,
  634. prepend = function(self, right)
  635. self._value = prepend_value(self._info, self._value, right)
  636. self:_set()
  637. end,
  638. __pow = function(self, right)
  639. return make_option(self._name, prepend_value(self._info, self._value, right))
  640. end,
  641. remove = function(self, right)
  642. self._value = remove_value(self._info, self._value, right)
  643. self:_set()
  644. end,
  645. __sub = function(self, right)
  646. return make_option(self._name, remove_value(self._info, self._value, right))
  647. end,
  648. }
  649. option_mt.__index = option_mt
  650. return setmetatable({}, {
  651. __index = function(_, k)
  652. -- vim.opt_global must get global value only
  653. -- vim.opt_local may fall back to global value like vim.opt
  654. local opts = { scope = scope == 'global' and 'global' or nil }
  655. return make_option(k, api.nvim_get_option_value(k, opts))
  656. end,
  657. __newindex = function(_, k, v)
  658. make_option(k, v):_set()
  659. end,
  660. })
  661. end
  662. --- @brief <pre>help
  663. --- *vim.opt_local*
  664. --- *vim.opt_global*
  665. --- *vim.opt*
  666. ---
  667. ---
  668. --- A special interface |vim.opt| exists for conveniently interacting with list-
  669. --- and map-style option from Lua: It allows accessing them as Lua tables and
  670. --- offers object-oriented method for adding and removing entries.
  671. ---
  672. --- Examples: ~
  673. ---
  674. --- The following methods of setting a list-style option are equivalent:
  675. --- In Vimscript: >vim
  676. --- set wildignore=*.o,*.a,__pycache__
  677. --- <
  678. --- In Lua using `vim.o`: >lua
  679. --- vim.o.wildignore = '*.o,*.a,__pycache__'
  680. --- <
  681. --- In Lua using `vim.opt`: >lua
  682. --- vim.opt.wildignore = { '*.o', '*.a', '__pycache__' }
  683. --- <
  684. --- To replicate the behavior of |:set+=|, use: >lua
  685. ---
  686. --- vim.opt.wildignore:append { "*.pyc", "node_modules" }
  687. --- <
  688. --- To replicate the behavior of |:set^=|, use: >lua
  689. ---
  690. --- vim.opt.wildignore:prepend { "new_first_value" }
  691. --- <
  692. --- To replicate the behavior of |:set-=|, use: >lua
  693. ---
  694. --- vim.opt.wildignore:remove { "node_modules" }
  695. --- <
  696. --- The following methods of setting a map-style option are equivalent:
  697. --- In Vimscript: >vim
  698. --- set listchars=space:_,tab:>~
  699. --- <
  700. --- In Lua using `vim.o`: >lua
  701. --- vim.o.listchars = 'space:_,tab:>~'
  702. --- <
  703. --- In Lua using `vim.opt`: >lua
  704. --- vim.opt.listchars = { space = '_', tab = '>~' }
  705. --- <
  706. ---
  707. --- Note that |vim.opt| returns an `Option` object, not the value of the option,
  708. --- which is accessed through |vim.opt:get()|:
  709. ---
  710. --- Examples: ~
  711. ---
  712. --- The following methods of getting a list-style option are equivalent:
  713. --- In Vimscript: >vim
  714. --- echo wildignore
  715. --- <
  716. --- In Lua using `vim.o`: >lua
  717. --- print(vim.o.wildignore)
  718. --- <
  719. --- In Lua using `vim.opt`: >lua
  720. --- vim.print(vim.opt.wildignore:get())
  721. --- <
  722. ---
  723. --- In any of the above examples, to replicate the behavior |:setlocal|, use
  724. --- `vim.opt_local`. Additionally, to replicate the behavior of |:setglobal|, use
  725. --- `vim.opt_global`.
  726. --- </pre>
  727. --- @nodoc
  728. --- @class vim.Option
  729. local Option = {} -- luacheck: no unused
  730. --- Returns a Lua-representation of the option. Boolean, number and string
  731. --- values will be returned in exactly the same fashion.
  732. ---
  733. --- For values that are comma-separated lists, an array will be returned with
  734. --- the values as entries in the array:
  735. ---
  736. --- ```lua
  737. --- vim.cmd [[set wildignore=*.pyc,*.o]]
  738. ---
  739. --- vim.print(vim.opt.wildignore:get())
  740. --- -- { "*.pyc", "*.o", }
  741. ---
  742. --- for _, ignore_pattern in ipairs(vim.opt.wildignore:get()) do
  743. --- print("Will ignore:", ignore_pattern)
  744. --- end
  745. --- -- Will ignore: *.pyc
  746. --- -- Will ignore: *.o
  747. --- ```
  748. ---
  749. --- For values that are comma-separated maps, a table will be returned with
  750. --- the names as keys and the values as entries:
  751. ---
  752. --- ```lua
  753. --- vim.cmd [[set listchars=space:_,tab:>~]]
  754. ---
  755. --- vim.print(vim.opt.listchars:get())
  756. --- -- { space = "_", tab = ">~", }
  757. ---
  758. --- for char, representation in pairs(vim.opt.listchars:get()) do
  759. --- print(char, "=>", representation)
  760. --- end
  761. --- ```
  762. ---
  763. --- For values that are lists of flags, a set will be returned with the flags
  764. --- as keys and `true` as entries.
  765. ---
  766. --- ```lua
  767. --- vim.cmd [[set formatoptions=njtcroql]]
  768. ---
  769. --- vim.print(vim.opt.formatoptions:get())
  770. --- -- { n = true, j = true, c = true, ... }
  771. ---
  772. --- local format_opts = vim.opt.formatoptions:get()
  773. --- if format_opts.j then
  774. --- print("J is enabled!")
  775. --- end
  776. --- ```
  777. ---@return string|integer|boolean|nil value of option
  778. function Option:get() end
  779. --- Append a value to string-style options. See |:set+=|
  780. ---
  781. --- These are equivalent:
  782. ---
  783. --- ```lua
  784. --- vim.opt.formatoptions:append('j')
  785. --- vim.opt.formatoptions = vim.opt.formatoptions + 'j'
  786. --- ```
  787. ---@param value string Value to append
  788. ---@diagnostic disable-next-line:unused-local used for gen_vimdoc
  789. function Option:append(value) end -- luacheck: no unused
  790. --- Prepend a value to string-style options. See |:set^=|
  791. ---
  792. --- These are equivalent:
  793. ---
  794. --- ```lua
  795. --- vim.opt.wildignore:prepend('*.o')
  796. --- vim.opt.wildignore = vim.opt.wildignore ^ '*.o'
  797. --- ```
  798. ---@param value string Value to prepend
  799. ---@diagnostic disable-next-line:unused-local used for gen_vimdoc
  800. function Option:prepend(value) end -- luacheck: no unused
  801. --- Remove a value from string-style options. See |:set-=|
  802. ---
  803. --- These are equivalent:
  804. ---
  805. --- ```lua
  806. --- vim.opt.wildignore:remove('*.pyc')
  807. --- vim.opt.wildignore = vim.opt.wildignore - '*.pyc'
  808. --- ```
  809. ---@param value string Value to remove
  810. ---@diagnostic disable-next-line:unused-local used for gen_vimdoc
  811. function Option:remove(value) end -- luacheck: no unused
  812. ---@private
  813. vim.opt = create_option_accessor()
  814. ---@private
  815. vim.opt_local = create_option_accessor('local')
  816. ---@private
  817. vim.opt_global = create_option_accessor('global')