feat(eval): mark getenv() as api-fast #42703

Problem:
`vim.env` (`vim.fn.getenv`) fails in a fast context (luv callbacks, LSP
rpc).

Solution:
Mark `getenv()` as |api-fast|. `vim_getenv()` never tickles `os_breakcheck()`.
This commit is contained in:
Justin M. Keyes authored and GitHub committed 2026-11-05 06:19:50 -05:00
1 parent d4e9653ed5
commit 094621e4c9
5 files changed
+17 -6

No files matched your search

+4 -4
View File
@@ -575,10 +575,10 @@ VIMSCRIPT
• |v:useractive| indicates user activity.
• |serverlist()| with `info=true` returns details for each server (own + peers).
• These Vimscript functions may be called from |api-fast| context (e.g.
|vim.uv| timer/handle callbacks): |keytrans()|, |char2nr()|, |nr2char()|,
|str2list()|, |strpart()|, |strcharpart()|, |strgetchar()|, |strchars()|,
|strcharlen()|, |strlen()|, |strdisplaywidth()|, |byteidx()|, |charidx()|,
|utf16idx()|, |tr()|, |trim()|.
|vim.uv| timer/handle callbacks): |getenv()|, |keytrans()|, |char2nr()|,
|nr2char()|, |str2list()|, |strpart()|, |strcharpart()|, |strgetchar()|,
|strchars()|, |strcharlen()|, |strlen()|, |strdisplaywidth()|, |byteidx()|,
|charidx()|, |utf16idx()|, |tr()|, |trim()|.
==============================================================================
CHANGED FEATURES *news-changed*
+3
View File
@@ -3816,6 +3816,9 @@ getenv({name}) *getenv()*
is different from a variable set to an empty string.
See also |expr-env|.
Attributes: ~
|api-fast|
Parameters: ~
• {name} (`string`)
+1 -2
View File
@@ -102,8 +102,7 @@ local function default_format_func(min_level, level, ...)
local info = debug.getinfo(3, 'Sl')
-- Full path (`short_src` is truncated), with $VIMRUNTIME abbreviated.
local src = info and (info.source:match('^@(.*)') or info.short_src) or '?'
local vimruntime = vim.uv.os_getenv('VIMRUNTIME') -- Use `vim.uv` for api-fast (e.g. LSP rpc).
local rt_path = vimruntime and vim.fs.relpath(vimruntime, src)
local rt_path = vim.env.VIMRUNTIME and vim.fs.relpath(vim.env.VIMRUNTIME, src)
local header = string.format(
'[%s][%s] %s:%s',
level_names[level],
+1
View File
@@ -4161,6 +4161,7 @@ M.funcs = {
See also |expr-env|.
]=],
fast = true,
name = 'getenv',
params = { { 'name', 'string' } },
returns = 'string',
+8
View File
@@ -12,6 +12,7 @@ describe('|api-fast| functions', function()
it('callable in a fast event', function()
local out = exec_lua(function()
local result
vim.uv.os_setenv('XTEST_FAST', 'x')
local timer = assert(vim.uv.new_timer())
timer:start(0, 0, function()
timer:close()
@@ -21,6 +22,7 @@ describe('|api-fast| functions', function()
byteidx = vim.fn.byteidx('héllo', 2),
char2nr = vim.fn.char2nr('A'),
charidx = vim.fn.charidx('héllo', 3),
getenv = vim.env.XTEST_FAST,
in_fast = vim.in_fast_event(),
keycode = vim.keycode('<C-a>'),
keytrans = vim.fn.keytrans(vim.keycode('<C-Home>')),
@@ -55,6 +57,7 @@ describe('|api-fast| functions', function()
byteidx = 3,
char2nr = 65,
charidx = 2,
getenv = 'x',
in_fast = true,
keycode = '\1', -- <C-a>
keytrans = '<C-Home>',
@@ -108,6 +111,11 @@ describe('|api-fast| functions', function()
charidx = function()
vim.fn.charidx(big, 500000)
end,
getenv = function()
-- Unset, so getenv() computes it.
vim.env.VIMRUNTIME = nil
vim.fn.getenv('VIMRUNTIME')
end,
keycode = function()
vim.keycode('<C-a>')
end,