_options.lua 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  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|. Works like `:set`, so buffer/window-scoped options target the current
  217. --- buffer/window. Invalid key is an error.
  218. ---
  219. --- Example:
  220. ---
  221. --- ```lua
  222. --- vim.o.cmdheight = 4
  223. --- print(vim.o.columns)
  224. --- print(vim.o.foo) -- error: invalid key
  225. --- ```
  226. vim.o = setmetatable({}, {
  227. __index = function(_, k)
  228. return api.nvim_get_option_value(k, {})
  229. end,
  230. __newindex = function(_, k, v)
  231. return api.nvim_set_option_value(k, v, {})
  232. end,
  233. })
  234. --- Get or set global |options|. Like `:setglobal`. Invalid key is
  235. --- an error.
  236. ---
  237. --- Note: this is different from |vim.o| because this accesses the global
  238. --- option value and thus is mostly useful for use with |global-local|
  239. --- options.
  240. ---
  241. --- Example:
  242. ---
  243. --- ```lua
  244. --- vim.go.cmdheight = 4
  245. --- print(vim.go.columns)
  246. --- print(vim.go.bar) -- error: invalid key
  247. --- ```
  248. vim.go = setmetatable({}, {
  249. __index = function(_, k)
  250. return api.nvim_get_option_value(k, { scope = 'global' })
  251. end,
  252. __newindex = function(_, k, v)
  253. return api.nvim_set_option_value(k, v, { scope = 'global' })
  254. end,
  255. })
  256. --- Get or set buffer-scoped |options| for the buffer with number {bufnr}.
  257. --- Like `:setlocal`. If {bufnr} is omitted then the current buffer is used.
  258. --- Invalid {bufnr} or key is an error.
  259. ---
  260. --- Example:
  261. ---
  262. --- ```lua
  263. --- local bufnr = vim.api.nvim_get_current_buf()
  264. --- vim.bo[bufnr].buflisted = true -- same as vim.bo.buflisted = true
  265. --- print(vim.bo.comments)
  266. --- print(vim.bo.baz) -- error: invalid key
  267. --- ```
  268. vim.bo = new_buf_opt_accessor()
  269. --- Get or set window-scoped |options| for the window with handle {winid} and
  270. --- buffer with number {bufnr}. Like `:setlocal` if setting a |global-local| option
  271. --- or if {bufnr} is provided, like `:set` otherwise. If {winid} is omitted then
  272. --- the current window is used. Invalid {winid}, {bufnr} or key is an error.
  273. ---
  274. --- Note: only {bufnr} with value `0` (the current buffer in the window) is
  275. --- supported.
  276. ---
  277. --- Example:
  278. ---
  279. --- ```lua
  280. --- local winid = vim.api.nvim_get_current_win()
  281. --- vim.wo[winid].number = true -- same as vim.wo.number = true
  282. --- print(vim.wo.foldmarker)
  283. --- print(vim.wo.quux) -- error: invalid key
  284. --- vim.wo[winid][0].spell = false -- like ':setlocal nospell'
  285. --- ```
  286. vim.wo = new_win_opt_accessor()
  287. --- vim.opt, vim.opt_local and vim.opt_global implementation
  288. ---
  289. --- To be used as helpers for working with options within neovim.
  290. --- For information on how to use, see :help vim.opt
  291. --- Preserves the order and does not mutate the original list
  292. --- @generic T
  293. --- @param t T[]
  294. --- @return T[]
  295. local function remove_duplicate_values(t)
  296. --- @type table, table<any,true>
  297. local result, seen = {}, {}
  298. for _, v in
  299. ipairs(t --[[@as any[] ]])
  300. do
  301. if not seen[v] then
  302. table.insert(result, v)
  303. end
  304. seen[v] = true
  305. end
  306. return result
  307. end
  308. --- Check whether the OptionTypes is allowed for vim.opt
  309. --- If it does not match, throw an error which indicates which option causes the error.
  310. --- @param name any
  311. --- @param value any
  312. --- @param types string[]
  313. local function assert_valid_value(name, value, types)
  314. local type_of_value = type(value)
  315. for _, valid_type in ipairs(types) do
  316. if valid_type == type_of_value then
  317. return
  318. end
  319. end
  320. error(
  321. string.format(
  322. "Invalid option type '%s' for '%s', should be %s",
  323. type_of_value,
  324. name,
  325. table.concat(types, ' or ')
  326. )
  327. )
  328. end
  329. local function passthrough(_, x)
  330. return x
  331. end
  332. local function tbl_merge(left, right)
  333. return vim.tbl_extend('force', left, right)
  334. end
  335. --- @param t table<any,any>
  336. --- @param value any|any[]
  337. local function tbl_remove(t, value)
  338. if type(value) == 'string' then
  339. t[value] = nil
  340. else
  341. for _, v in ipairs(value) do
  342. t[v] = nil
  343. end
  344. end
  345. return t
  346. end
  347. local valid_types = {
  348. boolean = { 'boolean' },
  349. number = { 'number' },
  350. string = { 'string' },
  351. set = { 'string', 'table' },
  352. array = { 'string', 'table' },
  353. map = { 'string', 'table' },
  354. }
  355. -- Map of functions to take a Lua style value and convert to vimoption_T style value.
  356. -- Each function takes (info, lua_value) -> vim_value
  357. local to_vim_value = {
  358. boolean = passthrough,
  359. number = passthrough,
  360. string = passthrough,
  361. --- @param info vim._option.Info
  362. --- @param value string|table<string,true>
  363. set = function(info, value)
  364. if type(value) == 'string' then
  365. return value
  366. end
  367. if info.flaglist and info.commalist then
  368. local keys = {}
  369. for k, v in pairs(value) do
  370. if v then
  371. table.insert(keys, k)
  372. end
  373. end
  374. table.sort(keys)
  375. return table.concat(keys, ',')
  376. else
  377. local result = ''
  378. for k, v in pairs(value) do
  379. if v then
  380. result = result .. k
  381. end
  382. end
  383. return result
  384. end
  385. end,
  386. --- @param info vim._option.Info
  387. --- @param value string|string[]
  388. array = function(info, value)
  389. if type(value) == 'string' then
  390. return value
  391. end
  392. if not info.allows_duplicates then
  393. value = remove_duplicate_values(value)
  394. end
  395. return table.concat(value, ',')
  396. end,
  397. --- @param value string|table<string,string>
  398. map = function(_, value)
  399. if type(value) == 'string' then
  400. return value
  401. end
  402. local result = {}
  403. for opt_key, opt_value in pairs(value) do
  404. table.insert(result, string.format('%s:%s', opt_key, opt_value))
  405. end
  406. table.sort(result)
  407. return table.concat(result, ',')
  408. end,
  409. }
  410. --- Convert a Lua value to a vimoption_T value
  411. local function convert_value_to_vim(name, info, value)
  412. if value == nil then
  413. return vim.NIL
  414. end
  415. assert_valid_value(name, value, valid_types[info.metatype])
  416. return to_vim_value[info.metatype](info, value)
  417. end
  418. -- Map of OptionType to functions that take vimoption_T values and convert to Lua values.
  419. -- Each function takes (info, vim_value) -> lua_value
  420. local to_lua_value = {
  421. boolean = passthrough,
  422. number = passthrough,
  423. string = passthrough,
  424. array = function(info, value)
  425. if type(value) == 'table' then
  426. if not info.allows_duplicates then
  427. value = remove_duplicate_values(value)
  428. end
  429. return value
  430. end
  431. -- Empty strings mean that there is nothing there,
  432. -- so empty table should be returned.
  433. if value == '' then
  434. return {}
  435. end
  436. -- Handles unescaped commas in a list.
  437. if value:find(',,,') then
  438. --- @type string, string
  439. local left, right = unpack(vim.split(value, ',,,'))
  440. local result = {}
  441. vim.list_extend(result, vim.split(left, ','))
  442. table.insert(result, ',')
  443. vim.list_extend(result, vim.split(right, ','))
  444. table.sort(result)
  445. return result
  446. end
  447. if value:find(',^,,', 1, true) then
  448. --- @type string, string
  449. local left, right = unpack(vim.split(value, ',^,,', { plain = true }))
  450. local result = {}
  451. vim.list_extend(result, vim.split(left, ','))
  452. table.insert(result, '^,')
  453. vim.list_extend(result, vim.split(right, ','))
  454. table.sort(result)
  455. return result
  456. end
  457. return vim.split(value, ',')
  458. end,
  459. set = function(info, value)
  460. if type(value) == 'table' then
  461. return value
  462. end
  463. -- Empty strings mean that there is nothing there,
  464. -- so empty table should be returned.
  465. if value == '' then
  466. return {}
  467. end
  468. assert(info.flaglist, 'That is the only one I know how to handle')
  469. local result = {} --- @type table<string,true>
  470. if info.flaglist and info.commalist then
  471. local split_value = vim.split(value, ',')
  472. for _, v in ipairs(split_value) do
  473. result[v] = true
  474. end
  475. else
  476. for i = 1, #value do
  477. result[value:sub(i, i)] = true
  478. end
  479. end
  480. return result
  481. end,
  482. map = function(info, raw_value)
  483. if type(raw_value) == 'table' then
  484. return raw_value
  485. end
  486. assert(info.commalist, 'Only commas are supported currently')
  487. local result = {} --- @type table<string,string>
  488. local comma_split = vim.split(raw_value, ',')
  489. for _, key_value_str in ipairs(comma_split) do
  490. --- @type string, string
  491. local key, value = unpack(vim.split(key_value_str, ':'))
  492. key = vim.trim(key)
  493. result[key] = value
  494. end
  495. return result
  496. end,
  497. }
  498. --- Converts a vimoption_T style value to a Lua value
  499. local function convert_value_to_lua(info, option_value)
  500. return to_lua_value[info.metatype](info, option_value)
  501. end
  502. local prepend_methods = {
  503. number = function()
  504. error("The '^' operator is not currently supported for")
  505. end,
  506. string = function(left, right)
  507. return right .. left
  508. end,
  509. array = function(left, right)
  510. for i = #right, 1, -1 do
  511. table.insert(left, 1, right[i])
  512. end
  513. return left
  514. end,
  515. map = tbl_merge,
  516. set = tbl_merge,
  517. }
  518. --- Handles the '^' operator
  519. local function prepend_value(info, current, new)
  520. return prepend_methods[info.metatype](
  521. convert_value_to_lua(info, current),
  522. convert_value_to_lua(info, new)
  523. )
  524. end
  525. local add_methods = {
  526. --- @param left integer
  527. --- @param right integer
  528. number = function(left, right)
  529. return left + right
  530. end,
  531. --- @param left string
  532. --- @param right string
  533. string = function(left, right)
  534. return left .. right
  535. end,
  536. --- @param left string[]
  537. --- @param right string[]
  538. --- @return string[]
  539. array = function(left, right)
  540. for _, v in ipairs(right) do
  541. table.insert(left, v)
  542. end
  543. return left
  544. end,
  545. map = tbl_merge,
  546. set = tbl_merge,
  547. }
  548. --- Handles the '+' operator
  549. local function add_value(info, current, new)
  550. return add_methods[info.metatype](
  551. convert_value_to_lua(info, current),
  552. convert_value_to_lua(info, new)
  553. )
  554. end
  555. --- @param t table<any,any>
  556. --- @param val any
  557. local function remove_one_item(t, val)
  558. if vim.islist(t) then
  559. local remove_index = nil
  560. for i, v in ipairs(t) do
  561. if v == val then
  562. remove_index = i
  563. end
  564. end
  565. if remove_index then
  566. table.remove(t, remove_index)
  567. end
  568. else
  569. t[val] = nil
  570. end
  571. end
  572. local remove_methods = {
  573. --- @param left integer
  574. --- @param right integer
  575. number = function(left, right)
  576. return left - right
  577. end,
  578. string = function()
  579. error('Subtraction not supported for strings.')
  580. end,
  581. --- @param left string[]
  582. --- @param right string[]
  583. --- @return string[]
  584. array = function(left, right)
  585. if type(right) == 'string' then
  586. remove_one_item(left, right)
  587. else
  588. for _, v in ipairs(right) do
  589. remove_one_item(left, v)
  590. end
  591. end
  592. return left
  593. end,
  594. map = tbl_remove,
  595. set = tbl_remove,
  596. }
  597. --- Handles the '-' operator
  598. local function remove_value(info, current, new)
  599. return remove_methods[info.metatype](convert_value_to_lua(info, current), new)
  600. end
  601. local function create_option_accessor(scope)
  602. --- @diagnostic disable-next-line: no-unknown
  603. local option_mt
  604. local function make_option(name, value)
  605. local info = assert(get_options_info(name), 'Not a valid option name: ' .. name)
  606. if type(value) == 'table' and getmetatable(value) == option_mt then
  607. assert(name == value._name, "must be the same value, otherwise that's weird.")
  608. --- @diagnostic disable-next-line: no-unknown
  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. --- @diagnostic disable-next-line: no-unknown
  629. self._value = add_value(self._info, self._value, right)
  630. self:_set()
  631. end,
  632. __add = function(self, right)
  633. return make_option(self._name, add_value(self._info, self._value, right))
  634. end,
  635. prepend = function(self, right)
  636. --- @diagnostic disable-next-line: no-unknown
  637. self._value = prepend_value(self._info, self._value, right)
  638. self:_set()
  639. end,
  640. __pow = function(self, right)
  641. return make_option(self._name, prepend_value(self._info, self._value, right))
  642. end,
  643. remove = function(self, right)
  644. --- @diagnostic disable-next-line: no-unknown
  645. self._value = remove_value(self._info, self._value, right)
  646. self:_set()
  647. end,
  648. __sub = function(self, right)
  649. return make_option(self._name, remove_value(self._info, self._value, right))
  650. end,
  651. }
  652. option_mt.__index = option_mt
  653. return setmetatable({}, {
  654. __index = function(_, k)
  655. -- vim.opt_global must get global value only
  656. -- vim.opt_local may fall back to global value like vim.opt
  657. local opts = { scope = scope == 'global' and 'global' or nil }
  658. return make_option(k, api.nvim_get_option_value(k, opts))
  659. end,
  660. __newindex = function(_, k, v)
  661. make_option(k, v):_set()
  662. end,
  663. })
  664. end
  665. --- @brief <pre>help
  666. --- *vim.opt_local*
  667. --- *vim.opt_global*
  668. --- *vim.opt*
  669. ---
  670. ---
  671. --- A special interface |vim.opt| exists for conveniently interacting with list-
  672. --- and map-style options from Lua: It allows accessing them as Lua tables and
  673. --- offers object-oriented method for adding and removing entries.
  674. ---
  675. --- Examples: ~
  676. ---
  677. --- The following methods of setting a list-style option are equivalent:
  678. --- In Vimscript: >vim
  679. --- set wildignore=*.o,*.a,__pycache__
  680. --- <
  681. --- In Lua using `vim.o`: >lua
  682. --- vim.o.wildignore = '*.o,*.a,__pycache__'
  683. --- <
  684. --- In Lua using `vim.opt`: >lua
  685. --- vim.opt.wildignore = { '*.o', '*.a', '__pycache__' }
  686. --- <
  687. --- To replicate the behavior of |:set+=|, use: >lua
  688. ---
  689. --- vim.opt.wildignore:append { "*.pyc", "node_modules" }
  690. --- <
  691. --- To replicate the behavior of |:set^=|, use: >lua
  692. ---
  693. --- vim.opt.wildignore:prepend { "new_first_value" }
  694. --- <
  695. --- To replicate the behavior of |:set-=|, use: >lua
  696. ---
  697. --- vim.opt.wildignore:remove { "node_modules" }
  698. --- <
  699. --- The following methods of setting a map-style option are equivalent:
  700. --- In Vimscript: >vim
  701. --- set listchars=space:_,tab:>~
  702. --- <
  703. --- In Lua using `vim.o`: >lua
  704. --- vim.o.listchars = 'space:_,tab:>~'
  705. --- <
  706. --- In Lua using `vim.opt`: >lua
  707. --- vim.opt.listchars = { space = '_', tab = '>~' }
  708. --- <
  709. ---
  710. --- Note that |vim.opt| returns an `Option` object, not the value of the option,
  711. --- which is accessed through |vim.opt:get()|:
  712. ---
  713. --- Examples: ~
  714. ---
  715. --- The following methods of getting a list-style option are equivalent:
  716. --- In Vimscript: >vim
  717. --- echo wildignore
  718. --- <
  719. --- In Lua using `vim.o`: >lua
  720. --- print(vim.o.wildignore)
  721. --- <
  722. --- In Lua using `vim.opt`: >lua
  723. --- vim.print(vim.opt.wildignore:get())
  724. --- <
  725. ---
  726. --- In any of the above examples, to replicate the behavior |:setlocal|, use
  727. --- `vim.opt_local`. Additionally, to replicate the behavior of |:setglobal|, use
  728. --- `vim.opt_global`.
  729. --- </pre>
  730. --- @nodoc
  731. --- @class vim.Option
  732. local Option = {} -- luacheck: no unused
  733. --- Returns a Lua-representation of the option. Boolean, number and string
  734. --- values will be returned in exactly the same fashion.
  735. ---
  736. --- For values that are comma-separated lists, an array will be returned with
  737. --- the values as entries in the array:
  738. ---
  739. --- ```lua
  740. --- vim.cmd [[set wildignore=*.pyc,*.o]]
  741. ---
  742. --- vim.print(vim.opt.wildignore:get())
  743. --- -- { "*.pyc", "*.o", }
  744. ---
  745. --- for _, ignore_pattern in ipairs(vim.opt.wildignore:get()) do
  746. --- print("Will ignore:", ignore_pattern)
  747. --- end
  748. --- -- Will ignore: *.pyc
  749. --- -- Will ignore: *.o
  750. --- ```
  751. ---
  752. --- For values that are comma-separated maps, a table will be returned with
  753. --- the names as keys and the values as entries:
  754. ---
  755. --- ```lua
  756. --- vim.cmd [[set listchars=space:_,tab:>~]]
  757. ---
  758. --- vim.print(vim.opt.listchars:get())
  759. --- -- { space = "_", tab = ">~", }
  760. ---
  761. --- for char, representation in pairs(vim.opt.listchars:get()) do
  762. --- print(char, "=>", representation)
  763. --- end
  764. --- ```
  765. ---
  766. --- For values that are lists of flags, a set will be returned with the flags
  767. --- as keys and `true` as entries.
  768. ---
  769. --- ```lua
  770. --- vim.cmd [[set formatoptions=njtcroql]]
  771. ---
  772. --- vim.print(vim.opt.formatoptions:get())
  773. --- -- { n = true, j = true, c = true, ... }
  774. ---
  775. --- local format_opts = vim.opt.formatoptions:get()
  776. --- if format_opts.j then
  777. --- print("J is enabled!")
  778. --- end
  779. --- ```
  780. ---@return string|integer|boolean|nil value of option
  781. function Option:get() end
  782. --- Append a value to string-style options. See |:set+=|
  783. ---
  784. --- These are equivalent:
  785. ---
  786. --- ```lua
  787. --- vim.opt.formatoptions:append('j')
  788. --- vim.opt.formatoptions = vim.opt.formatoptions + 'j'
  789. --- ```
  790. ---@param value string Value to append
  791. ---@diagnostic disable-next-line:unused-local used for gen_vimdoc
  792. function Option:append(value) end -- luacheck: no unused
  793. --- Prepend a value to string-style options. See |:set^=|
  794. ---
  795. --- These are equivalent:
  796. ---
  797. --- ```lua
  798. --- vim.opt.wildignore:prepend('*.o')
  799. --- vim.opt.wildignore = vim.opt.wildignore ^ '*.o'
  800. --- ```
  801. ---@param value string Value to prepend
  802. ---@diagnostic disable-next-line:unused-local used for gen_vimdoc
  803. function Option:prepend(value) end -- luacheck: no unused
  804. --- Remove a value from string-style options. See |:set-=|
  805. ---
  806. --- These are equivalent:
  807. ---
  808. --- ```lua
  809. --- vim.opt.wildignore:remove('*.pyc')
  810. --- vim.opt.wildignore = vim.opt.wildignore - '*.pyc'
  811. --- ```
  812. ---@param value string Value to remove
  813. ---@diagnostic disable-next-line:unused-local used for gen_vimdoc
  814. function Option:remove(value) end -- luacheck: no unused
  815. --- @nodoc
  816. vim.opt = create_option_accessor()
  817. --- @nodoc
  818. vim.opt_local = create_option_accessor('local')
  819. --- @nodoc
  820. vim.opt_global = create_option_accessor('global')