Skip to content

Commit

Permalink
feat(vim._with): allow specifying scope-specific options
Browse files Browse the repository at this point in the history
Replace `options` context with `bo`, `wo` and `go` contexts. This allows
users to specify which scope the option should work on.

Also add `env` context for changing `vim.env`.

Closes neovim#29253.
  • Loading branch information
dundargoc committed Jun 10, 2024
1 parent 743c580 commit 972c9f9
Showing 1 changed file with 71 additions and 14 deletions.
85 changes: 71 additions & 14 deletions runtime/lua/vim/shared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1141,8 +1141,10 @@ end

--- @nodoc
--- @class vim.context.mods
--- @field bo? table<string, any>
--- @field buf? integer
--- @field emsg_silent? boolean
--- @field go? table<string, any>
--- @field hide? boolean
--- @field horizontal? boolean
--- @field keepalt? boolean
Expand All @@ -1151,11 +1153,13 @@ end
--- @field keeppatterns? boolean
--- @field lockmarks? boolean
--- @field noautocmd? boolean
--- @field options? table<string, any>
--- @field o? table<string, any>
--- @field sandbox? boolean
--- @field silent? boolean
--- @field unsilent? boolean
--- @field win? integer
--- @field wo? table<string, any>
--- @field env? table<string, any>

--- Executes function `f` with the given context specification.
---
Expand All @@ -1164,8 +1168,11 @@ function vim._with(context, f)
vim.validate('context', context, 'table')
vim.validate('f', f, 'function')

vim.validate('context.bo', context.bo, 'table', true)
vim.validate('context.buf', context.buf, 'number', true)
vim.validate('context.emsg_silent', context.emsg_silent, 'boolean', true)
vim.validate('context.env', context.wo, 'table', true)
vim.validate('context.go', context.go, 'table', true)
vim.validate('context.hide', context.hide, 'boolean', true)
vim.validate('context.horizontal', context.horizontal, 'boolean', true)
vim.validate('context.keepalt', context.keepalt, 'boolean', true)
Expand All @@ -1174,11 +1181,11 @@ function vim._with(context, f)
vim.validate('context.keeppatterns', context.keeppatterns, 'boolean', true)
vim.validate('context.lockmarks', context.lockmarks, 'boolean', true)
vim.validate('context.noautocmd', context.noautocmd, 'boolean', true)
vim.validate('context.options', context.options, 'table', true)
vim.validate('context.sandbox', context.sandbox, 'boolean', true)
vim.validate('context.silent', context.silent, 'boolean', true)
vim.validate('context.unsilent', context.unsilent, 'boolean', true)
vim.validate('context.win', context.win, 'number', true)
vim.validate('context.wo', context.wo, 'table', true)

-- Check buffer exists
if context.buf then
Expand All @@ -1194,23 +1201,73 @@ function vim._with(context, f)
end
end

-- Store original options
local previous_options ---@type table<string, any>
if context.options then
previous_options = {}
for k, v in pairs(context.options) do
previous_options[k] =
vim.api.nvim_get_option_value(k, { win = context.win, buf = context.buf })
vim.api.nvim_set_option_value(k, v, { win = context.win, buf = context.buf })
-- Store and change buffer options
local bo_prev ---@type table<string, any>
if context.bo then
bo_prev = {}
for k, v in pairs(context.bo) do
bo_prev[k] = vim.bo[k]
vim.bo[k] = v ---@type any
end
end

-- Store and change window options
local wo_prev ---@type table<string, any>
if context.wo then
wo_prev = {}
for k, v in pairs(context.wo) do
wo_prev[k] = vim.wo[k]
vim.wo[k] = v ---@type any
end
end

-- Store and change global options
local go_prev ---@type table<string, any>
if context.go then
go_prev = {}
for k, v in pairs(context.go) do
go_prev[k] = vim.go[k]
vim.go[k] = v ---@type any
end
end

-- Store and change global options
local env_prev ---@type table<string, any>
if context.env then
env_prev = {}
for k, v in pairs(context.env) do
env_prev[k] = vim.env[k]
vim.env[k] = v ---@type any
end
end

local retval = { vim._with_c(context, f) }

-- Restore original options
if previous_options then
for k, v in pairs(previous_options) do
vim.api.nvim_set_option_value(k, v, { win = context.win, buf = context.buf })
-- Restore buffer options
if bo_prev then
for k, v in pairs(bo_prev) do
vim.bo[k] = v ---@type any
end
end

-- Restore window options
if wo_prev then
for k, v in pairs(wo_prev) do
vim.wo[k] = v ---@type any
end
end

-- Restore global options
if go_prev then
for k, v in pairs(go_prev) do
vim.go[k] = v ---@type any
end
end

-- Restore environment
if env_prev then
for k, v in pairs(env_prev) do
vim.env[k] = v ---@type any
end
end

Expand Down

0 comments on commit 972c9f9

Please sign in to comment.