diff options
| author | Peter Cardenas <16930781+PeterCardenas@users.noreply.github.com> | 2026-04-24 08:57:35 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-24 11:57:35 -0400 |
| commit | 27191e0f4f4f9086180a8fbe3e52c1c280a70b09 (patch) | |
| tree | 7db425cbd45fbc5a32ed2a937691bdd7019d6cbc | |
| parent | a57fab2f2d852ec33bdbcb7fc8b90d611e6a653b (diff) | |
feat(api): nvim_echo(percent=nil) means "unknown" progress #39029
Problem:
No way to signal "unknown" or "indeterminate" progress percentage.
Solution:
Treat percent=nil as "indeterminate" percent.
| -rw-r--r-- | runtime/doc/api.txt | 3 | ||||
| -rw-r--r-- | runtime/doc/news.txt | 2 | ||||
| -rw-r--r-- | runtime/lua/vim/_core/defaults.lua | 7 | ||||
| -rw-r--r-- | runtime/lua/vim/_meta/api.gen.lua | 2 | ||||
| -rw-r--r-- | runtime/lua/vim/health.lua | 9 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 11 | ||||
| -rw-r--r-- | src/nvim/message.c | 7 | ||||
| -rw-r--r-- | test/functional/ui/messages_spec.lua | 2 |
8 files changed, 27 insertions, 16 deletions
diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index cc7c1d8e82..604dddebdd 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -695,7 +695,8 @@ nvim_echo({chunks}, {history}, {opts}) *nvim_echo()* • kind (`string?`) Decides the |ui-messages| kind in the emitted message. Set "progress" to emit a |progress-message|. - • percent (`integer?`) |progress-message| percentage. + • percent (`integer?`) |progress-message| percentage, or + nil to signal "unknown progress". • source (`string?`) |progress-message| source. • status (`string?`) |progress-message| status: • "success": Process completed successfully. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 977cc1fd91..d47a39fdc9 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -112,6 +112,8 @@ API • |nvim_set_hl()| supports "font" key. • |nvim_open_win()| `zindex` controls whether the UI will use a dimmed cursor shape when an unfocused float is on top of the cursor. +• |nvim_echo()| distinguishes zero percent from omitted percent for Progress + events. BUILD diff --git a/runtime/lua/vim/_core/defaults.lua b/runtime/lua/vim/_core/defaults.lua index 84623726c7..80327e0fc7 100644 --- a/runtime/lua/vim/_core/defaults.lua +++ b/runtime/lua/vim/_core/defaults.lua @@ -1115,7 +1115,12 @@ do desc = 'Display native progress bars', callback = function(ev) if ev.data.status == 'running' then - vim.api.nvim_ui_send(string.format('\027]9;4;1;%d\027\\', ev.data.percent)) + if ev.data.percent ~= nil then + vim.api.nvim_ui_send(string.format('\027]9;4;1;%d\027\\', ev.data.percent)) + else + -- "Indeterminate" progress (unknown percent). + vim.api.nvim_ui_send(string.format('\027]9;4;3\027\\')) + end else vim.api.nvim_ui_send('\027]9;4;0;0\027\\') end diff --git a/runtime/lua/vim/_meta/api.gen.lua b/runtime/lua/vim/_meta/api.gen.lua index 85e5912593..990ee81925 100644 --- a/runtime/lua/vim/_meta/api.gen.lua +++ b/runtime/lua/vim/_meta/api.gen.lua @@ -1139,7 +1139,7 @@ function vim.api.nvim_del_var(name) end --- instead of creating a new message. --- - kind (`string?`) Decides the `ui-messages` kind in the emitted message. Set "progress" --- to emit a `progress-message`. ---- - percent (`integer?`) `progress-message` percentage. +--- - percent (`integer?`) `progress-message` percentage, or nil to signal "unknown progress". --- - source (`string?`) `progress-message` source. --- - status (`string?`) `progress-message` status: --- - "success": Process completed successfully. diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index 10b066b4d3..faa9d4246b 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -373,15 +373,14 @@ end ---Emit progress messages ---@param len integer ----@return fun(status: 'success'|'running', idx: integer, fmt: string, ...: any): nil +---@return fun(status: 'success'|'running', idx: integer?, fmt: string, ...: any): nil local function progress_report(len) local progress = { kind = 'progress', source = 'vim.health', title = 'checkhealth' } return function(status, idx, fmt, ...) progress.status = status - progress.percent = status == 'success' and nil or math.floor(idx / len * 100) - -- percent=0 omits the reporting of percentage, so use 1% instead - -- progress.percent = progress.percent == 0 and 1 or progress.percent + local progress_percent = idx and math.floor(idx / len * 100) or nil + progress.percent = status == 'success' and nil or progress_percent progress.id = vim.api.nvim_echo({ { fmt:format(...) } }, false, progress) vim.cmd.redraw() end @@ -500,7 +499,7 @@ function M._check(eap) vim.fn.append(vim.fn.line('$'), s_output) end - progress_msg('success', 0, 'checks done') + progress_msg('success', nil, 'checks done') -- Quit with 'q' inside healthcheck buffers. vim._with({ buf = bufnr }, function() diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 9adc4914a8..ce9018a218 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -824,7 +824,7 @@ void nvim_set_vvar(String name, Object value, Error *err) /// instead of creating a new message. /// - kind (`string?`) Decides the |ui-messages| kind in the emitted message. Set "progress" /// to emit a |progress-message|. -/// - percent (`integer?`) |progress-message| percentage. +/// - percent (`integer?`) |progress-message| percentage, or nil to signal "unknown progress". /// - source (`string?`) |progress-message| source. /// - status (`string?`) |progress-message| status: /// - "success": Process completed successfully. @@ -857,7 +857,7 @@ Union(Integer, String) nvim_echo(ArrayOf(Tuple(String, *HLGroupID)) chunks, Bool bool needs_clear = !history; VALIDATE(is_progress - || (opts->status.size == 0 && opts->title.size == 0 && opts->percent == 0 + || (opts->status.size == 0 && opts->title.size == 0 && !HAS_KEY(opts, echo_opts, percent) && opts->data.size == 0 && opts->source.size == 0), "Conflict: title/source/status/percent/data not allowed with kind='%s'", kind, { @@ -872,7 +872,8 @@ Union(Integer, String) nvim_echo(ArrayOf(Tuple(String, *HLGroupID)) chunks, Bool goto error; }); - VALIDATE_RANGE(!is_progress || (opts->percent >= 0 && opts->percent <= 100), + VALIDATE_RANGE(!is_progress || !HAS_KEY(opts, echo_opts, percent) + || (opts->percent >= 0 && opts->percent <= 100), "percent", { goto error; }); @@ -888,8 +889,8 @@ Union(Integer, String) nvim_echo(ArrayOf(Tuple(String, *HLGroupID)) chunks, Bool }); MessageData msg_data = { .title = opts->title, .status = opts->status, - .percent = opts->percent, .data = opts->data, - .source = opts->source }; + .percent = HAS_KEY(opts, echo_opts, percent) ? opts->percent : -1, + .data = opts->data, .source = opts->source }; const bool save_nwr = need_wait_return; const int save_lines_left = lines_left; diff --git a/src/nvim/message.c b/src/nvim/message.c index 1d7c24ce02..5b5a6ba2f8 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -337,7 +337,7 @@ static HlMessage format_progress_message(HlMessage hl_msg, MessageData *msg_data ((HlMessageChunk){ .text = copy_string(msg_data->title, NULL), .hl_id = hl_id })); kv_push(updated_msg, ((HlMessageChunk){ .text = cstr_to_string(": "), .hl_id = 0 })); } - if (msg_data->percent > 0) { + if (msg_data->percent >= 0) { char percent_buf[10]; vim_snprintf(percent_buf, sizeof(percent_buf), "%3ld%% ", (long)msg_data->percent); String percent = cstr_to_string(percent_buf); @@ -1173,7 +1173,10 @@ void do_autocmd_progress(MsgID msg_id, HlMessage msg, MessageData *msg_data) PUT_C(data, "id", OBJECT_OBJ(msg_id)); PUT_C(data, "text", ARRAY_OBJ(messages)); if (msg_data != NULL) { - PUT_C(data, "percent", INTEGER_OBJ(msg_data->percent)); + if (msg_data->percent >= 0) { + // If percent=nil we omit it, it means "indeterminate progress". #39029 + PUT_C(data, "percent", INTEGER_OBJ(msg_data->percent)); + } PUT_C(data, "source", STRING_OBJ(msg_data->source)); PUT_C(data, "status", STRING_OBJ(msg_data->status)); PUT_C(data, "title", STRING_OBJ(msg_data->title)); diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 16030dd82d..861882c296 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -3613,7 +3613,7 @@ describe('progress-message', function() eq( "Conflict: title/source/status/percent/data not allowed with kind='echo'", - t.pcall_err(api.nvim_echo, { { 'test-message' } }, false, { percent = 10 }) + t.pcall_err(api.nvim_echo, { { 'test-message' } }, false, { percent = 0 }) ) eq( |
