feat(excmd): add :uptime command #39331

Problem
Nvim marks its v:starttime, but there is no user-friendly way to get Nvim's uptime.

Solution
Add :uptime (based loosely on uptime(1)).
This commit is contained in:
Olivia Kinnear
2026-04-23 16:11:59 -05:00
committed by GitHub
parent c42aea3d37
commit 645a588aa6
11 changed files with 133 additions and 3 deletions

View File

@@ -1,6 +1,8 @@
local api = vim.api
local fs = vim.fs
local time = require('vim._core.time')
local util = require('vim._core.util')
local uv = vim.uv
local N_ = vim.fn.gettext
--- Parsed ex command arguments for builtin commands, passed from C via `nlua_call_excmd`.
@@ -157,7 +159,7 @@ local available_subcmds = vim.tbl_keys(actions)
--- Implements command: `:lsp {subcmd} {name}?`.
--- @param eap vim._core.ExCmdArgs
M.ex_lsp = function(eap)
function M.ex_lsp(eap)
local fargs = api.nvim_parse_cmd('lsp ' .. eap.args, {}).args
if not fargs then
return
@@ -198,7 +200,7 @@ local log_dir = vim.fn.stdpath('log')
--- Implements command: `:log {file}`.
--- @param eap vim._core.ExCmdArgs
M.ex_log = function(eap)
function M.ex_log(eap)
local filename = eap.args
if filename == '' then
util.wrapped_edit(log_dir, eap.smods)
@@ -236,7 +238,7 @@ end
--- `:terminal [cmd]`
--- @param eap vim._core.ExCmdArgs
--- @param shell_argv? string[] Tokenized 'shell' from C (shell_build_argv), for the no-cmd case.
M.ex_terminal = function(eap, shell_argv)
function M.ex_terminal(eap, shell_argv)
local smods = eap.smods
local has_mods = (smods.tab or 0) > 0
or (smods.split or '') ~= ''
@@ -256,4 +258,10 @@ M.ex_terminal = function(eap, shell_argv)
end
end
function M.ex_uptime()
local uptime = math.floor((uv.hrtime() - vim.v.starttime) / 1e9)
local uptime_display = time.fmt_rtime(uptime)
api.nvim_echo({ { N_('Up %s'):format(uptime_display) } }, true, {})
end
return M

View File

@@ -0,0 +1,35 @@
local N_ = vim.fn.gettext
local M = {}
--- @param seconds_in_unit integer How many seconds make up the unit.
--- @param singular string The singular name of the unit. ("1 second")
--- @param fplural string The plural name of the unit, to format. ("%s seconds")
--- @param times string[] Working list of uptime strings.
--- @param remaining integer Remaining time, in seconds.
--- @return integer remaining Remaining time.
local function time_part(seconds_in_unit, singular, fplural, times, remaining)
local unit = math.floor(remaining / seconds_in_unit)
if unit ~= 0 or #times ~= 0 or seconds_in_unit == 1 then
local display = unit == 1 and singular or fplural:format(unit)
times[#times + 1] = display
end
return remaining % seconds_in_unit
end
--- Display seconds in a pretty form (e.g. "1 hour, 24 minutes, 13 seconds").
---
--- @param seconds integer Time in seconds.
--- @return string time Pretty representation of the time.
function M.fmt_rtime(seconds)
local times = {}
seconds = time_part(86400, N_('1 day'), N_('%s days'), times, seconds)
seconds = time_part(3600, N_('1 hour'), N_('%s hours'), times, seconds)
seconds = time_part(60, N_('1 minute'), N_('%s minutes'), times, seconds)
seconds = time_part(1, N_('1 second'), N_('%s seconds'), times, seconds)
assert(seconds == 0)
return table.concat(times, ', ')
end
return M