mirror of
https://github.com/neovim/neovim.git
synced 2026-08-01 05:09:08 +00:00
feat(:restart): v:startreason #40186
Problem:
It's clumsy for scripts to handle a "restart", without custom mappings or
global vars.
Solution:
Introduce `v:startreason`
(cherry picked from commit ae426ee465)
This commit is contained in:
committed by
Olivia Kinnear
parent
a4985ac902
commit
611b4f8237
@@ -81,7 +81,8 @@ Restart Nvim
|
||||
|
||||
1. Stops Nvim using `:qall` (or |+cmd|, if given).
|
||||
2. Starts a new Nvim server using the same |v:argv| (except
|
||||
`-- [file…]` files).
|
||||
`-- [file…]` files). Sets |v:startreason| to "restart" on the
|
||||
new server.
|
||||
3. Attaches all UIs to the new Nvim server and runs `[command]`
|
||||
on it.
|
||||
|
||||
|
||||
@@ -453,6 +453,7 @@ VIMSCRIPT
|
||||
• |v:vim_did_init| is set after sourcing |init.vim| but before |load-plugins|.
|
||||
• |prompt_appendbuf()| appends text to prompt-buffer.
|
||||
• |v:exitreason| is set before |QuitPre|.
|
||||
• |v:startreason| differentiates between restart and normal start.
|
||||
• |v:starttime| is the process start time (nanoseconds since UNIX epoch).
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -434,7 +434,7 @@ Initialization *initialization* *startup*
|
||||
At startup, Nvim checks environment variables and files and sets values
|
||||
accordingly, proceeding as follows:
|
||||
|
||||
1. Set |v:starttime|.
|
||||
1. Set |v:starttime| and |v:startreason|.
|
||||
|
||||
2. Set the 'shell' option. *SHELL* *COMSPEC*
|
||||
The environment variable SHELL, if it exists, is used to set the 'shell'
|
||||
|
||||
@@ -633,6 +633,14 @@ v:stacktrace
|
||||
stack trace. See also |v:exception|, |v:throwpoint|, and
|
||||
|throw-variables|.
|
||||
|
||||
*v:startreason* *startreason-variable*
|
||||
v:startreason
|
||||
The reason Nvim started. Possible values:
|
||||
- "normal" normal startup.
|
||||
- "restart" started by |:restart| or |ZR|.
|
||||
|
||||
Read-only.
|
||||
|
||||
*v:starttime* *starttime-variable*
|
||||
v:starttime
|
||||
Timestamp (nanoseconds since UNIX epoch) when the Nvim process
|
||||
|
||||
8
runtime/lua/vim/_meta/vvars.gen.lua
generated
8
runtime/lua/vim/_meta/vvars.gen.lua
generated
@@ -667,6 +667,14 @@ vim.v.shell_error = ...
|
||||
--- @type table[]
|
||||
vim.v.stacktrace = ...
|
||||
|
||||
--- The reason Nvim started. Possible values:
|
||||
--- - "normal" normal startup.
|
||||
--- - "restart" started by `:restart` or `ZR`.
|
||||
---
|
||||
--- Read-only.
|
||||
--- @type string
|
||||
vim.v.startreason = ...
|
||||
|
||||
--- Timestamp (nanoseconds since UNIX epoch) when the Nvim process
|
||||
--- started.
|
||||
---
|
||||
|
||||
@@ -217,6 +217,7 @@ static struct vimvar {
|
||||
VV(VV_VIRTNUM, "virtnum", VAR_NUMBER, VV_RO),
|
||||
VV(VV_STARTTIME, "starttime", VAR_NUMBER, VV_RO),
|
||||
VV(VV_EXITREASON, "exitreason", VAR_STRING, VV_RO),
|
||||
VV(VV_STARTREASON, "startreason", VAR_STRING, VV_RO),
|
||||
};
|
||||
#undef VV
|
||||
|
||||
@@ -316,6 +317,7 @@ void evalvars_init(void)
|
||||
set_vim_var_nr(VV_SEARCHFORWARD, 1);
|
||||
set_vim_var_nr(VV_HLSEARCH, 1);
|
||||
set_vim_var_nr(VV_COUNT1, 1);
|
||||
set_vim_var_string(VV_STARTREASON, S_LEN("normal"));
|
||||
set_vim_var_special(VV_EXITING, kSpecialVarNull);
|
||||
|
||||
set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
|
||||
@@ -345,6 +347,15 @@ void evalvars_init(void)
|
||||
set_vim_var_partial(VV_LUA, vvlua_partial);
|
||||
|
||||
set_reg_var(0); // default for v:register is not 0 but '"'
|
||||
|
||||
// Set v:startreason via environment variable
|
||||
const char *startreason = os_getenv_noalloc(ENV_STARTREASON);
|
||||
if (strequal(startreason, "normal") || strequal(startreason, "restart")) {
|
||||
set_vim_var_string(VV_STARTREASON, startreason, -1);
|
||||
}
|
||||
if (os_env_exists(ENV_STARTREASON, false)) {
|
||||
os_unsetenv(ENV_STARTREASON);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(EXITFREE)
|
||||
|
||||
@@ -137,4 +137,5 @@ typedef enum {
|
||||
VV_VIRTNUM,
|
||||
VV_STARTTIME,
|
||||
VV_EXITREASON,
|
||||
VV_STARTREASON,
|
||||
} VimVarIndex;
|
||||
|
||||
@@ -5057,6 +5057,10 @@ static void ex_restart(exarg_T *eap)
|
||||
restart_alloc_console_env = true;
|
||||
}
|
||||
#endif
|
||||
bool startreason_env = false;
|
||||
if (os_setenv(ENV_STARTREASON, "restart", 1) == 0) {
|
||||
startreason_env = true;
|
||||
}
|
||||
|
||||
CallbackReader on_err = CALLBACK_READER_INIT;
|
||||
#ifdef MSWIN
|
||||
@@ -5073,6 +5077,9 @@ static void ex_restart(exarg_T *eap)
|
||||
CALLBACK_READER_INIT, on_err, CALLBACK_NONE,
|
||||
false, true, true, detach, kChannelStdinPipe,
|
||||
NULL, 0, 0, NULL, &exit_status);
|
||||
if (startreason_env) {
|
||||
os_unsetenv(ENV_STARTREASON);
|
||||
}
|
||||
#ifdef MSWIN
|
||||
if (restart_alloc_console_env) {
|
||||
os_unsetenv("__NVIM_RESTART_ALLOC_CONSOLE");
|
||||
|
||||
@@ -26,3 +26,4 @@ extern char *default_lib_dir;
|
||||
|
||||
#define ENV_LOGFILE "NVIM_LOG_FILE"
|
||||
#define ENV_NVIM "NVIM"
|
||||
#define ENV_STARTREASON "__NVIM_STARTREASON"
|
||||
|
||||
@@ -765,6 +765,16 @@ M.vars = {
|
||||
Read-only.
|
||||
]=],
|
||||
},
|
||||
startreason = {
|
||||
type = 'string',
|
||||
desc = [=[
|
||||
The reason Nvim started. Possible values:
|
||||
- "normal" normal startup.
|
||||
- "restart" started by |:restart| or |ZR|.
|
||||
|
||||
Read-only.
|
||||
]=],
|
||||
},
|
||||
statusmsg = {
|
||||
type = 'string',
|
||||
desc = [=[
|
||||
|
||||
@@ -364,7 +364,15 @@ it(':restart works in headless server (no UI)', function()
|
||||
n.set_session(nil)
|
||||
end)
|
||||
|
||||
fn.jobstart({ n.nvim_prog, '--clean', '--headless', '--listen', server_pipe })
|
||||
fn.jobstart({
|
||||
n.nvim_prog,
|
||||
'--clean',
|
||||
'--headless',
|
||||
'--listen',
|
||||
server_pipe,
|
||||
'--cmd',
|
||||
'let g:early_startreason = v:startreason',
|
||||
})
|
||||
t.retry(nil, nil, function()
|
||||
neq(nil, vim.uv.fs_stat(server_pipe))
|
||||
end)
|
||||
@@ -373,6 +381,8 @@ it(':restart works in headless server (no UI)', function()
|
||||
n.expect_exit(n.command, 'restart')
|
||||
n.set_session(n.connect(server_pipe))
|
||||
eq(1, api.nvim_get_vvar('vim_did_enter'))
|
||||
eq('restart', api.nvim_get_vvar('startreason'))
|
||||
eq('restart', n.eval('g:early_startreason'))
|
||||
|
||||
-- TODO: [command] is currently not executed without UI
|
||||
-- n.expect_exit(n.command, 'restart lua _G.new_server = 1')
|
||||
|
||||
@@ -48,3 +48,11 @@ describe('v:argf', function()
|
||||
eq({ abs1, abs2, abs3 }, n.eval('v:argf'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('v:startreason', function()
|
||||
it('is read-only and starts as "normal"', function()
|
||||
n.clear { args = { '--cmd', 'let g:early_startreason = v:startreason' } }
|
||||
eq('normal', eval('g:early_startreason'))
|
||||
t.matches('E46', t.pcall_err(command, "let v:startreason = 'restart'"))
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user