aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/F.lua8
-rw-r--r--runtime/lua/vim/_editor.lua50
-rw-r--r--runtime/lua/vim/_init_packages.lua3
-rw-r--r--runtime/lua/vim/_meta.lua869
-rw-r--r--runtime/lua/vim/compat.lua12
-rw-r--r--runtime/lua/vim/diagnostic.lua45
-rw-r--r--runtime/lua/vim/filetype.lua95
-rw-r--r--runtime/lua/vim/filetype/detect.lua13
-rw-r--r--runtime/lua/vim/fs.lua56
-rw-r--r--runtime/lua/vim/highlight.lua2
-rw-r--r--runtime/lua/vim/inspect.lua32
-rw-r--r--runtime/lua/vim/keymap.lua31
-rw-r--r--runtime/lua/vim/lsp.lua118
-rw-r--r--runtime/lua/vim/lsp/buf.lua280
-rw-r--r--runtime/lua/vim/lsp/handlers.lua49
-rw-r--r--runtime/lua/vim/lsp/protocol.lua2
-rw-r--r--runtime/lua/vim/lsp/rpc.lua781
-rw-r--r--runtime/lua/vim/lsp/util.lua174
-rw-r--r--runtime/lua/vim/shared.lua94
-rw-r--r--runtime/lua/vim/treesitter.lua269
-rw-r--r--runtime/lua/vim/treesitter/health.lua2
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua155
-rw-r--r--runtime/lua/vim/treesitter/language.lua22
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua143
-rw-r--r--runtime/lua/vim/treesitter/query.lua170
25 files changed, 1890 insertions, 1585 deletions
diff --git a/runtime/lua/vim/F.lua b/runtime/lua/vim/F.lua
index bca5ddf68b..3e370c0a84 100644
--- a/runtime/lua/vim/F.lua
+++ b/runtime/lua/vim/F.lua
@@ -2,8 +2,12 @@ local F = {}
--- Returns {a} if it is not nil, otherwise returns {b}.
---
----@param a
----@param b
+---@generic A
+---@generic B
+---
+---@param a A
+---@param b B
+---@return A | B
function F.if_nil(a, b)
if a == nil then
return b
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua
index b8a7f71145..28e5897aa9 100644
--- a/runtime/lua/vim/_editor.lua
+++ b/runtime/lua/vim/_editor.lua
@@ -12,21 +12,8 @@
-- Guideline: "If in doubt, put it in the runtime".
--
-- Most functions should live directly in `vim.`, not in submodules.
--- The only "forbidden" names are those claimed by legacy `if_lua`:
--- $ vim
--- :lua for k,v in pairs(vim) do print(k) end
--- buffer
--- open
--- window
--- lastline
--- firstline
--- type
--- line
--- eval
--- dict
--- beep
--- list
--- command
+--
+-- Compatibility with Vim's `if_lua` is explicitly a non-goal.
--
-- Reference (#6580):
-- - https://github.com/luafun/luafun
@@ -36,8 +23,6 @@
-- - https://github.com/bakpakin/Fennel (pretty print, repl)
-- - https://github.com/howl-editor/howl/tree/master/lib/howl/util
-local vim = assert(vim)
-
-- These are for loading runtime modules lazily since they aren't available in
-- the nvim binary as specified in executor.c
for k, v in pairs({
@@ -122,9 +107,7 @@ function vim._os_proc_children(ppid)
return children
end
--- TODO(ZyX-I): Create compatibility layer.
-
---- Return a human-readable representation of the given object.
+--- Gets a human-readable representation of the given object.
---
---@see https://github.com/kikito/inspect.lua
---@see https://github.com/mpeterv/vinspect
@@ -152,14 +135,15 @@ do
--- </pre>
---
---@see |paste|
+ ---@alias paste_phase -1 | 1 | 2 | 3
---
- ---@param lines |readfile()|-style list of lines to paste. |channel-lines|
- ---@param phase -1: "non-streaming" paste: the call contains all lines.
+ ---@param lines string[] # |readfile()|-style list of lines to paste. |channel-lines|
+ ---@param phase paste_phase -1: "non-streaming" paste: the call contains all lines.
--- If paste is "streamed", `phase` indicates the stream state:
--- - 1: starts the paste (exactly once)
--- - 2: continues the paste (zero or more times)
--- - 3: ends the paste (exactly once)
- ---@returns false if client should cancel the paste.
+ ---@returns boolean # false if client should cancel the paste.
function vim.paste(lines, phase)
local now = vim.loop.now()
local is_first_chunk = phase < 2
@@ -255,6 +239,8 @@ end
---@see |lua-loop-callbacks|
---@see |vim.schedule()|
---@see |vim.in_fast_event()|
+---@param cb function
+---@return function
function vim.schedule_wrap(cb)
return function(...)
local args = vim.F.pack_len(...)
@@ -399,11 +385,11 @@ end
--- Get a table of lines with start, end columns for a region marked by two points
---
---@param bufnr number of buffer
----@param pos1 (line, column) tuple marking beginning of region
----@param pos2 (line, column) tuple marking end of region
----@param regtype type of selection (:help setreg)
+---@param pos1 integer[] (line, column) tuple marking beginning of region
+---@param pos2 integer[] (line, column) tuple marking end of region
+---@param regtype string type of selection, see |setreg()|
---@param inclusive boolean indicating whether the selection is end-inclusive
----@return region lua table of the form {linenr = {startcol,endcol}}
+---@return table<integer, {}> region lua table of the form {linenr = {startcol,endcol}}
function vim.region(bufnr, pos1, pos2, regtype, inclusive)
if not vim.api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
@@ -448,11 +434,11 @@ end
--- Defers calling `fn` until `timeout` ms passes.
---
--- Use to do a one-shot timer that calls `fn`
---- Note: The {fn} is |schedule_wrap|ped automatically, so API functions are
+--- Note: The {fn} is |vim.schedule_wrap()|ped automatically, so API functions are
--- safe to call.
----@param fn Callback to call once `timeout` expires
----@param timeout Number of milliseconds to wait before calling `fn`
----@return timer luv timer object
+---@param fn function Callback to call once `timeout` expires
+---@param timeout integer Number of milliseconds to wait before calling `fn`
+---@return table timer luv timer object
function vim.defer_fn(fn, timeout)
vim.validate({ fn = { fn, 'c', true } })
local timer = vim.loop.new_timer()
@@ -758,7 +744,7 @@ end
--- local hl_normal = vim.pretty_print(vim.api.nvim_get_hl_by_name("Normal", true))
---</pre>
---@see |vim.inspect()|
----@return given arguments.
+---@return any # given arguments.
function vim.pretty_print(...)
local objects = {}
for i = 1, select('#', ...) do
diff --git a/runtime/lua/vim/_init_packages.lua b/runtime/lua/vim/_init_packages.lua
index 7e3c73667e..19c8608732 100644
--- a/runtime/lua/vim/_init_packages.lua
+++ b/runtime/lua/vim/_init_packages.lua
@@ -1,6 +1,3 @@
--- prevents luacheck from making lints for setting things on vim
-local vim = assert(vim)
-
local pathtrails = {}
vim._so_trails = {}
for s in (package.cpath .. ';'):gmatch('[^;]*;') do
diff --git a/runtime/lua/vim/_meta.lua b/runtime/lua/vim/_meta.lua
index f1652718ee..9c7972873e 100644
--- a/runtime/lua/vim/_meta.lua
+++ b/runtime/lua/vim/_meta.lua
@@ -1,173 +1,113 @@
--- prevents luacheck from making lints for setting things on vim
-local vim = assert(vim)
-
local a = vim.api
-local validate = vim.validate
-
-local SET_TYPES = setmetatable({
- SET = 0,
- LOCAL = 1,
- GLOBAL = 2,
-}, { __index = error })
-
-local options_info = nil
-local buf_options = nil
-local glb_options = nil
-local win_options = nil
-
-local function _setup()
- if options_info ~= nil then
- return
- end
- options_info = {}
- for _, v in pairs(a.nvim_get_all_options_info()) do
- options_info[v.name] = v
- if v.shortname ~= '' then
- options_info[v.shortname] = v
- end
- end
- local function get_scoped_options(scope)
- local result = {}
- for name, option_info in pairs(options_info) do
- if option_info.scope == scope then
- result[name] = true
+-- TODO(tjdevries): Improve option metadata so that this doesn't have to be hardcoded.
+-- Can be done in a separate PR.
+local key_value_options = {
+ fillchars = true,
+ fcs = true,
+ listchars = true,
+ lcs = true,
+ winhighlight = true,
+ winhl = true,
+}
+
+--- Convert a vimoption_T style dictionary to the correct OptionType associated with it.
+---@return string
+local function get_option_metatype(name, info)
+ if info.type == 'string' then
+ if info.flaglist then
+ return 'set'
+ elseif info.commalist then
+ if key_value_options[name] then
+ return 'map'
end
+ return 'array'
end
-
- return result
+ return 'string'
end
-
- buf_options = get_scoped_options('buf')
- glb_options = get_scoped_options('global')
- win_options = get_scoped_options('win')
+ return info.type
end
-local function make_meta_accessor(get, set, del, validator)
- validator = validator or function()
- return true
- end
-
- validate({
- get = { get, 'f' },
- set = { set, 'f' },
- del = { del, 'f', true },
- validator = { validator, 'f' },
- })
+local options_info = setmetatable({}, {
+ __index = function(t, k)
+ local info = a.nvim_get_option_info(k)
+ info.metatype = get_option_metatype(k, info)
+ rawset(t, k, info)
+ return rawget(t, k)
+ end,
+})
- local mt = {}
- function mt:__newindex(k, v)
- if not validator(k) then
- return
+vim.env = setmetatable({}, {
+ __index = function(_, k)
+ local v = vim.fn.getenv(k)
+ if v == vim.NIL then
+ return nil
end
+ return v
+ end,
- if del and v == nil then
- return del(k)
- end
- return set(k, v)
- end
- function mt:__index(k)
- if not validator(k) then
- return
- end
+ __newindex = function(_, k, v)
+ vim.fn.setenv(k, v)
+ end,
+})
- return get(k)
+local function opt_validate(option_name, target_scope)
+ local scope = options_info[option_name].scope
+ if scope ~= target_scope then
+ local scope_to_string = { buf = 'buffer', win = 'window' }
+ error(
+ string.format(
+ [['%s' is a %s option, not a %s option. See ":help %s"]],
+ option_name,
+ scope_to_string[scope] or scope,
+ scope_to_string[target_scope] or target_scope,
+ option_name
+ )
+ )
end
- return setmetatable({}, mt)
end
-vim.env = make_meta_accessor(function(k)
- local v = vim.fn.getenv(k)
- if v == vim.NIL then
- return nil
- end
- return v
-end, vim.fn.setenv)
-
-do -- buffer option accessor
- local function new_buf_opt_accessor(bufnr)
- local function get(k)
- if bufnr == nil and type(k) == 'number' then
- return new_buf_opt_accessor(k)
- end
-
- return a.nvim_get_option_value(k, { buf = bufnr or 0 })
- end
-
- local function set(k, v)
- return a.nvim_set_option_value(k, v, { buf = bufnr or 0 })
- end
-
- return make_meta_accessor(get, set, nil, function(k)
- if type(k) == 'string' then
- _setup()
- if win_options[k] then
- error(
- string.format([['%s' is a window option, not a buffer option. See ":help %s"]], k, k)
- )
- elseif glb_options[k] then
- error(
- string.format([['%s' is a global option, not a buffer option. See ":help %s"]], k, k)
- )
- end
+local function new_opt_accessor(handle, scope)
+ return setmetatable({}, {
+ __index = function(_, k)
+ if handle == nil and type(k) == 'number' then
+ return new_opt_accessor(k, scope)
end
+ opt_validate(k, scope)
+ return a.nvim_get_option_value(k, { [scope] = handle or 0 })
+ end,
- return true
- end)
- end
-
- vim.bo = new_buf_opt_accessor(nil)
+ __newindex = function(_, k, v)
+ opt_validate(k, scope)
+ return a.nvim_set_option_value(k, v, { [scope] = handle or 0 })
+ end,
+ })
end
-do -- window option accessor
- local function new_win_opt_accessor(winnr)
- local function get(k)
- if winnr == nil and type(k) == 'number' then
- return new_win_opt_accessor(k)
- end
- return a.nvim_get_option_value(k, { win = winnr or 0 })
- end
-
- local function set(k, v)
- return a.nvim_set_option_value(k, v, { win = winnr or 0 })
- end
-
- return make_meta_accessor(get, set, nil, function(k)
- if type(k) == 'string' then
- _setup()
- if buf_options[k] then
- error(
- string.format([['%s' is a buffer option, not a window option. See ":help %s"]], k, k)
- )
- elseif glb_options[k] then
- error(
- string.format([['%s' is a global option, not a window option. See ":help %s"]], k, k)
- )
- end
- end
-
- return true
- end)
- end
-
- vim.wo = new_win_opt_accessor(nil)
-end
+vim.bo = new_opt_accessor(nil, 'buf')
+vim.wo = new_opt_accessor(nil, 'win')
-- vim global option
-- this ONLY sets the global option. like `setglobal`
-vim.go = make_meta_accessor(function(k)
- return a.nvim_get_option_value(k, { scope = 'global' })
-end, function(k, v)
- return a.nvim_set_option_value(k, v, { scope = 'global' })
-end)
+vim.go = setmetatable({}, {
+ __index = function(_, k)
+ return a.nvim_get_option_value(k, { scope = 'global' })
+ end,
+ __newindex = function(_, k, v)
+ return a.nvim_set_option_value(k, v, { scope = 'global' })
+ end,
+})
-- vim `set` style options.
-- it has no additional metamethod magic.
-vim.o = make_meta_accessor(function(k)
- return a.nvim_get_option_value(k, {})
-end, function(k, v)
- return a.nvim_set_option_value(k, v, {})
-end)
+vim.o = setmetatable({}, {
+ __index = function(_, k)
+ return a.nvim_get_option_value(k, {})
+ end,
+ __newindex = function(_, k, v)
+ return a.nvim_set_option_value(k, v, {})
+ end,
+})
---@brief [[
--- vim.opt, vim.opt_local and vim.opt_global implementation
@@ -178,11 +118,8 @@ end)
---@brief ]]
--- Preserves the order and does not mutate the original list
-local remove_duplicate_values = function(t)
+local function remove_duplicate_values(t)
local result, seen = {}, {}
- if type(t) == 'function' then
- error(debug.traceback('asdf'))
- end
for _, v in ipairs(t) do
if not seen[v] then
table.insert(result, v)
@@ -194,61 +131,6 @@ local remove_duplicate_values = function(t)
return result
end
--- TODO(tjdevries): Improve option metadata so that this doesn't have to be hardcoded.
--- Can be done in a separate PR.
-local key_value_options = {
- fillchars = true,
- listchars = true,
- winhl = true,
-}
-
----@class OptionTypes
---- Option Type Enum
-local OptionTypes = setmetatable({
- BOOLEAN = 0,
- NUMBER = 1,
- STRING = 2,
- ARRAY = 3,
- MAP = 4,
- SET = 5,
-}, {
- __index = function(_, k)
- error('Not a valid OptionType: ' .. k)
- end,
- __newindex = function(_, k)
- error('Cannot set a new OptionType: ' .. k)
- end,
-})
-
---- Convert a vimoption_T style dictionary to the correct OptionType associated with it.
----@return OptionType
-local get_option_type = function(name, info)
- if info.type == 'boolean' then
- return OptionTypes.BOOLEAN
- elseif info.type == 'number' then
- return OptionTypes.NUMBER
- elseif info.type == 'string' then
- if not info.commalist and not info.flaglist then
- return OptionTypes.STRING
- end
-
- if key_value_options[name] then
- assert(info.commalist, 'Must be a comma list to use key:value style')
- return OptionTypes.MAP
- end
-
- if info.flaglist then
- return OptionTypes.SET
- elseif info.commalist then
- return OptionTypes.ARRAY
- end
-
- error('Fallthrough in OptionTypes')
- else
- error('Not a known info.type:' .. info.type)
- end
-end
-
-- Check whether the OptionTypes is allowed for vim.opt
-- If it does not match, throw an error which indicates which option causes the error.
local function assert_valid_value(name, value, types)
@@ -269,373 +151,323 @@ local function assert_valid_value(name, value, types)
)
end
+local function passthrough(_, x)
+ return x
+end
+
+local function tbl_merge(left, right)
+ return vim.tbl_extend('force', left, right)
+end
+
+local function tbl_remove(t, value)
+ if type(value) == 'string' then
+ t[value] = nil
+ else
+ for _, v in ipairs(value) do
+ t[v] = nil
+ end
+ end
+
+ return t
+end
+
local valid_types = {
- [OptionTypes.BOOLEAN] = { 'boolean' },
- [OptionTypes.NUMBER] = { 'number' },
- [OptionTypes.STRING] = { 'string' },
- [OptionTypes.SET] = { 'string', 'table' },
- [OptionTypes.ARRAY] = { 'string', 'table' },
- [OptionTypes.MAP] = { 'string', 'table' },
+ boolean = { 'boolean' },
+ number = { 'number' },
+ string = { 'string' },
+ set = { 'string', 'table' },
+ array = { 'string', 'table' },
+ map = { 'string', 'table' },
}
---- Convert a lua value to a vimoption_T value
-local convert_value_to_vim = (function()
- -- Map of functions to take a Lua style value and convert to vimoption_T style value.
- -- Each function takes (info, lua_value) -> vim_value
- local to_vim_value = {
- [OptionTypes.BOOLEAN] = function(_, value)
- return value
- end,
- [OptionTypes.NUMBER] = function(_, value)
- return value
- end,
- [OptionTypes.STRING] = function(_, value)
- return value
- end,
-
- [OptionTypes.SET] = function(info, value)
- if type(value) == 'string' then
- return value
- end
+-- Map of functions to take a Lua style value and convert to vimoption_T style value.
+-- Each function takes (info, lua_value) -> vim_value
+local to_vim_value = {
+ boolean = passthrough,
+ number = passthrough,
+ string = passthrough,
- if info.flaglist and info.commalist then
- local keys = {}
- for k, v in pairs(value) do
- if v then
- table.insert(keys, k)
- end
- end
+ set = function(info, value)
+ if type(value) == 'string' then
+ return value
+ end
- table.sort(keys)
- return table.concat(keys, ',')
- else
- local result = ''
- for k, v in pairs(value) do
- if v then
- result = result .. k
- end
+ if info.flaglist and info.commalist then
+ local keys = {}
+ for k, v in pairs(value) do
+ if v then
+ table.insert(keys, k)
end
-
- return result
end
- end,
- [OptionTypes.ARRAY] = function(info, value)
- if type(value) == 'string' then
- return value
- end
- if not info.allows_duplicates then
- value = remove_duplicate_values(value)
+ table.sort(keys)
+ return table.concat(keys, ',')
+ else
+ local result = ''
+ for k, v in pairs(value) do
+ if v then
+ result = result .. k
+ end
end
- return table.concat(value, ',')
- end,
- [OptionTypes.MAP] = function(_, value)
- if type(value) == 'string' then
- return value
- end
+ return result
+ end
+ end,
- local result = {}
- for opt_key, opt_value in pairs(value) do
- table.insert(result, string.format('%s:%s', opt_key, opt_value))
- end
+ array = function(info, value)
+ if type(value) == 'string' then
+ return value
+ end
+ if not info.allows_duplicates then
+ value = remove_duplicate_values(value)
+ end
+ return table.concat(value, ',')
+ end,
- table.sort(result)
- return table.concat(result, ',')
- end,
- }
+ map = function(_, value)
+ if type(value) == 'string' then
+ return value
+ end
- return function(name, info, value)
- if value == nil then
- return vim.NIL
+ local result = {}
+ for opt_key, opt_value in pairs(value) do
+ table.insert(result, string.format('%s:%s', opt_key, opt_value))
end
- local option_type = get_option_type(name, info)
- assert_valid_value(name, value, valid_types[option_type])
+ table.sort(result)
+ return table.concat(result, ',')
+ end,
+}
- return to_vim_value[option_type](info, value)
+--- Convert a lua value to a vimoption_T value
+local function convert_value_to_vim(name, info, value)
+ if value == nil then
+ return vim.NIL
end
-end)()
---- Converts a vimoption_T style value to a Lua value
-local convert_value_to_lua = (function()
- -- Map of OptionType to functions that take vimoption_T values and convert to lua values.
- -- Each function takes (info, vim_value) -> lua_value
- local to_lua_value = {
- [OptionTypes.BOOLEAN] = function(_, value)
- return value
- end,
- [OptionTypes.NUMBER] = function(_, value)
- return value
- end,
- [OptionTypes.STRING] = function(_, value)
- return value
- end,
+ assert_valid_value(name, value, valid_types[info.metatype])
- [OptionTypes.ARRAY] = function(info, value)
- if type(value) == 'table' then
- if not info.allows_duplicates then
- value = remove_duplicate_values(value)
- end
+ return to_vim_value[info.metatype](info, value)
+end
- return value
- end
+-- Map of OptionType to functions that take vimoption_T values and convert to lua values.
+-- Each function takes (info, vim_value) -> lua_value
+local to_lua_value = {
+ boolean = passthrough,
+ number = passthrough,
+ string = passthrough,
- -- Empty strings mean that there is nothing there,
- -- so empty table should be returned.
- if value == '' then
- return {}
+ array = function(info, value)
+ if type(value) == 'table' then
+ if not info.allows_duplicates then
+ value = remove_duplicate_values(value)
end
- -- Handles unescaped commas in a list.
- if string.find(value, ',,,') then
- local comma_split = vim.split(value, ',,,')
- local left = comma_split[1]
- local right = comma_split[2]
+ return value
+ end
- local result = {}
- vim.list_extend(result, vim.split(left, ','))
- table.insert(result, ',')
- vim.list_extend(result, vim.split(right, ','))
+ -- Empty strings mean that there is nothing there,
+ -- so empty table should be returned.
+ if value == '' then
+ return {}
+ end
- table.sort(result)
+ -- Handles unescaped commas in a list.
+ if string.find(value, ',,,') then
+ local left, right = unpack(vim.split(value, ',,,'))
- return result
- end
+ local result = {}
+ vim.list_extend(result, vim.split(left, ','))
+ table.insert(result, ',')
+ vim.list_extend(result, vim.split(right, ','))
- if string.find(value, ',^,,', 1, true) then
- local comma_split = vim.split(value, ',^,,', true)
- local left = comma_split[1]
- local right = comma_split[2]
+ table.sort(result)
- local result = {}
- vim.list_extend(result, vim.split(left, ','))
- table.insert(result, '^,')
- vim.list_extend(result, vim.split(right, ','))
+ return result
+ end
- table.sort(result)
+ if string.find(value, ',^,,', 1, true) then
+ local left, right = unpack(vim.split(value, ',^,,', true))
- return result
- end
+ local result = {}
+ vim.list_extend(result, vim.split(left, ','))
+ table.insert(result, '^,')
+ vim.list_extend(result, vim.split(right, ','))
- return vim.split(value, ',')
- end,
+ table.sort(result)
- [OptionTypes.SET] = function(info, value)
- if type(value) == 'table' then
- return value
- end
+ return result
+ end
- -- Empty strings mean that there is nothing there,
- -- so empty table should be returned.
- if value == '' then
- return {}
- end
+ return vim.split(value, ',')
+ end,
- assert(info.flaglist, 'That is the only one I know how to handle')
+ set = function(info, value)
+ if type(value) == 'table' then
+ return value
+ end
- if info.flaglist and info.commalist then
- local split_value = vim.split(value, ',')
- local result = {}
- for _, v in ipairs(split_value) do
- result[v] = true
- end
+ -- Empty strings mean that there is nothing there,
+ -- so empty table should be returned.
+ if value == '' then
+ return {}
+ end
- return result
- else
- local result = {}
- for i = 1, #value do
- result[value:sub(i, i)] = true
- end
+ assert(info.flaglist, 'That is the only one I know how to handle')
- return result
+ if info.flaglist and info.commalist then
+ local split_value = vim.split(value, ',')
+ local result = {}
+ for _, v in ipairs(split_value) do
+ result[v] = true
end
- end,
- [OptionTypes.MAP] = function(info, raw_value)
- if type(raw_value) == 'table' then
- return raw_value
+ return result
+ else
+ local result = {}
+ for i = 1, #value do
+ result[value:sub(i, i)] = true
end
- assert(info.commalist, 'Only commas are supported currently')
-
- local result = {}
+ return result
+ end
+ end,
- local comma_split = vim.split(raw_value, ',')
- for _, key_value_str in ipairs(comma_split) do
- local key, value = unpack(vim.split(key_value_str, ':'))
- key = vim.trim(key)
+ map = function(info, raw_value)
+ if type(raw_value) == 'table' then
+ return raw_value
+ end
- result[key] = value
- end
+ assert(info.commalist, 'Only commas are supported currently')
- return result
- end,
- }
+ local result = {}
- return function(name, info, option_value)
- return to_lua_value[get_option_type(name, info)](info, option_value)
- end
-end)()
+ local comma_split = vim.split(raw_value, ',')
+ for _, key_value_str in ipairs(comma_split) do
+ local key, value = unpack(vim.split(key_value_str, ':'))
+ key = vim.trim(key)
---- Handles the mutation of various different values.
-local value_mutator = function(name, info, current, new, mutator)
- return mutator[get_option_type(name, info)](current, new)
-end
+ result[key] = value
+ end
---- Handles the '^' operator
-local prepend_value = (function()
- local methods = {
- [OptionTypes.NUMBER] = function()
- error("The '^' operator is not currently supported for")
- end,
+ return result
+ end,
+}
- [OptionTypes.STRING] = function(left, right)
- return right .. left
- end,
+--- Converts a vimoption_T style value to a Lua value
+local function convert_value_to_lua(info, option_value)
+ return to_lua_value[info.metatype](info, option_value)
+end
- [OptionTypes.ARRAY] = function(left, right)
- for i = #right, 1, -1 do
- table.insert(left, 1, right[i])
- end
+local prepend_methods = {
+ number = function()
+ error("The '^' operator is not currently supported for")
+ end,
- return left
- end,
+ string = function(left, right)
+ return right .. left
+ end,
- [OptionTypes.MAP] = function(left, right)
- return vim.tbl_extend('force', left, right)
- end,
+ array = function(left, right)
+ for i = #right, 1, -1 do
+ table.insert(left, 1, right[i])
+ end
- [OptionTypes.SET] = function(left, right)
- return vim.tbl_extend('force', left, right)
- end,
- }
+ return left
+ end,
- return function(name, info, current, new)
- return value_mutator(
- name,
- info,
- convert_value_to_lua(name, info, current),
- convert_value_to_lua(name, info, new),
- methods
- )
- end
-end)()
+ map = tbl_merge,
+ set = tbl_merge,
+}
---- Handles the '+' operator
-local add_value = (function()
- local methods = {
- [OptionTypes.NUMBER] = function(left, right)
- return left + right
- end,
+--- Handles the '^' operator
+local function prepend_value(info, current, new)
+ return prepend_methods[info.metatype](
+ convert_value_to_lua(info, current),
+ convert_value_to_lua(info, new)
+ )
+end
- [OptionTypes.STRING] = function(left, right)
- return left .. right
- end,
+local add_methods = {
+ number = function(left, right)
+ return left + right
+ end,
- [OptionTypes.ARRAY] = function(left, right)
- for _, v in ipairs(right) do
- table.insert(left, v)
- end
+ string = function(left, right)
+ return left .. right
+ end,
- return left
- end,
+ array = function(left, right)
+ for _, v in ipairs(right) do
+ table.insert(left, v)
+ end
- [OptionTypes.MAP] = function(left, right)
- return vim.tbl_extend('force', left, right)
- end,
+ return left
+ end,
- [OptionTypes.SET] = function(left, right)
- return vim.tbl_extend('force', left, right)
- end,
- }
+ map = tbl_merge,
+ set = tbl_merge,
+}
- return function(name, info, current, new)
- return value_mutator(
- name,
- info,
- convert_value_to_lua(name, info, current),
- convert_value_to_lua(name, info, new),
- methods
- )
- end
-end)()
+--- Handles the '+' operator
+local function add_value(info, current, new)
+ return add_methods[info.metatype](
+ convert_value_to_lua(info, current),
+ convert_value_to_lua(info, new)
+ )
+end
---- Handles the '-' operator
-local remove_value = (function()
-