summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorluukvbaal <luukvbaal@gmail.com>2026-04-21 22:11:41 +0200
committerGitHub <noreply@github.com>2026-04-21 16:11:41 -0400
commitff68fd6b8a84ce83c14358db1d70a562f1524ebe (patch)
tree211e14e618038a18783612fccc8e8d37287c08b2 /src
parentfe6026825883b44b09a8d3a03f2d49bfc8ed4725 (diff)
fix(messages): "progress" kind for busy messages #39280
Problem: The "Scanning:" completion, bufwrite, and indent (there may be more) messages which indicate progress can use the "progress" kind for their msg_show event. Indent message does not have a kind. Solution: Emit these messages with the "progress" kind. Set the message id to the replaced kind so that a UI knows to replace it (and to provide a migration path in case a UI was distinguishing these messages for whatever reason).
Diffstat (limited to 'src')
-rw-r--r--src/nvim/bufwrite.c6
-rw-r--r--src/nvim/fileio.c7
-rw-r--r--src/nvim/indent.c21
-rw-r--r--src/nvim/insexpand.c17
-rw-r--r--src/nvim/message.c27
5 files changed, 48 insertions, 30 deletions
diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c
index f45d01a289..4a14a1ecb2 100644
--- a/src/nvim/bufwrite.c
+++ b/src/nvim/bufwrite.c
@@ -1081,7 +1081,6 @@ int buf_write(buf_T *buf, char *fname, char *sfname, linenr_T start, linenr_T en
msg_scroll = true; // don't overwrite previous file message
}
if (!filtering) {
- msg_ext_set_kind("bufwrite");
// show that we are busy
#ifndef UNIX
filemess(buf, sfname, "");
@@ -1708,10 +1707,7 @@ restore_backup:
xstrlcat(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"), IOSIZE);
}
}
-
- msg_ext_set_kind("bufwrite");
- msg_ext_overwrite = true;
- set_keep_msg(msg_trunc(IObuff, false, 0), 0);
+ set_keep_msg(msg_progress(IObuff, "bufwrite", "success", 0, true, true), 0);
}
// When written everything correctly: reset 'modified'. Unless not
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 5b659cb91d..69a9ba0e2d 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -131,9 +131,12 @@ void filemess(buf_T *buf, char *name, char *s)
msg_scroll = msg_scroll_save;
msg_scrolled_ign = true;
// may truncate the message to avoid a hit-return prompt
- msg_outtrans(msg_may_trunc(false, IObuff), 0, false);
+ if (*s == NUL) {
+ msg_progress(IObuff, "bufwrite", "running", 0, false, true);
+ } else {
+ msg_outtrans(msg_may_trunc(false, IObuff), 0, false);
+ }
msg_clr_eos();
- ui_flush();
msg_scrolled_ign = false;
}
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index 806526b734..b10173135e 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -1004,19 +1004,20 @@ void op_reindent(oparg_T *oap, Indenter how)
if (i > 1
&& (i % 50 == 0 || i == oap->line_count - 1)
&& oap->line_count > p_report) {
- smsg(0, _("%" PRId64 " lines to indent... "), (int64_t)i);
+ snprintf(IObuff, IOSIZE, _("%" PRId64 " lines to indent... "), (int64_t)i);
+ // Restore cursor to avoid redrawing curwin in msg_show callback.
+ linenr_T save_lnum = curwin->w_cursor.lnum;
+ curwin->w_cursor.lnum = start_lnum;
+ msg_progress(IObuff, "indent", "running", 0, true, false);
+ curwin->w_cursor.lnum = save_lnum;
}
// Be vi-compatible: For lisp indenting the first line is not
// indented, unless there is only one line.
- if (i != oap->line_count - 1 || oap->line_count == 1
- || how != get_lisp_indent) {
+ if (i != oap->line_count - 1 || oap->line_count == 1 || how != get_lisp_indent) {
char *l = skipwhite(get_cursor_line_ptr());
- if (*l == NUL) { // empty or blank line
- amount = 0;
- } else {
- amount = how(); // get the indent for this line
- }
+ // Get indent for this line unless it is blank.
+ amount = *l == NUL ? 0 : how();
if (amount >= 0 && set_indent(amount, 0)) {
// did change the indent, call changed_lines() later
if (first_changed == 0) {
@@ -1047,7 +1048,9 @@ void op_reindent(oparg_T *oap, Indenter how)
if (oap->line_count > p_report) {
i = oap->line_count - (i + 1);
- smsg(0, NGETTEXT("%" PRId64 " line indented ", "%" PRId64 " lines indented ", i), (int64_t)i);
+ snprintf(IObuff, IOSIZE,
+ NGETTEXT("%" PRId64 " line indented ", "%" PRId64 " lines indented ", i), (int64_t)i);
+ msg_progress(IObuff, "indent", "success", 0, true, false);
}
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// set '[ and '] marks
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 6e986eb5fe..964c2517d6 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -1944,11 +1944,8 @@ static void ins_compl_files(int count, char **files, bool thesaurus, int flags,
for (int i = 0; i < count && !got_int && !ins_compl_interrupted(); i++) {
FILE *fp = os_fopen(files[i], "r"); // open dictionary file
if (flags != DICT_EXACT && !shortmess(SHM_COMPLETIONSCAN) && !compl_autocomplete) {
- msg_hist_off = true; // reset in msg_trunc()
- msg_ext_set_kind("completion");
- vim_snprintf(IObuff, IOSIZE,
- _("Scanning dictionary: %s"), files[i]);
- msg_trunc(IObuff, true, HLF_R);
+ vim_snprintf(IObuff, IOSIZE, _("Scanning dictionary: %s"), files[i]);
+ msg_progress(IObuff, "completion", "running", HLF_R, false, true);
}
if (fp == NULL) {
@@ -3823,16 +3820,13 @@ static int process_next_cpt_value(ins_compl_next_state_T *st, int *compl_type_ar
st->dict_f = DICT_EXACT;
}
if (!shortmess(SHM_COMPLETIONSCAN) && !compl_autocomplete) {
- msg_hist_off = true; // reset in msg_trunc()
- msg_ext_overwrite = true;
- msg_ext_set_kind("completion");
vim_snprintf(IObuff, IOSIZE, _("Scanning: %s"),
st->ins_buf->b_fname == NULL
? buf_spname(st->ins_buf)
: st->ins_buf->b_sfname == NULL
? st->ins_buf->b_fname
: st->ins_buf->b_sfname);
- msg_trunc(IObuff, true, HLF_R);
+ msg_progress(IObuff, "completion", "running", HLF_R, false, true);
}
} else if (*st->e_cpt == NUL) {
status = INS_COMPL_CPT_END;
@@ -3865,11 +3859,8 @@ static int process_next_cpt_value(ins_compl_next_state_T *st, int *compl_type_ar
} else if (*st->e_cpt == ']' || *st->e_cpt == 't') {
compl_type = CTRL_X_TAGS;
if (!shortmess(SHM_COMPLETIONSCAN) && !compl_autocomplete) {
- msg_ext_set_kind("completion");
- msg_hist_off = true; // reset in msg_trunc()
- msg_ext_overwrite = true;
vim_snprintf(IObuff, IOSIZE, "%s", _("Scanning tags."));
- msg_trunc(IObuff, true, HLF_R);
+ msg_progress(IObuff, "completion", "running", HLF_R, false, true);
}
}
}
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 4748bd1db9..1d7c24ce02 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -14,6 +14,7 @@
#include "klib/kvec.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
#include "nvim/buffer_defs.h"
@@ -387,7 +388,6 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
msg_clr_eos();
bool need_clear = false;
bool hl_msg_updated = false;
- msg_ext_history = history;
if (kind != NULL) {
msg_ext_set_kind(kind);
}
@@ -1099,6 +1099,31 @@ char *msg_may_trunc(bool force, char *s)
return s;
}
+char *msg_progress(char *s, char *id, char *status, int hl_id, bool hist, bool trunc)
+{
+ Error err = ERROR_INIT;
+ Dict(echo_opts) opts = {
+ .kind = cstr_as_string("progress"),
+ .source = cstr_as_string("nvim"),
+ .status = cstr_as_string(status),
+ .id = CSTR_AS_OBJ(id),
+ };
+ if (hist && (!trunc || ui_has(kUIMessages))) {
+ msg_hist_add(s, -1, 0);
+ }
+ if (trunc) {
+ s = msg_may_trunc(false, s);
+ }
+ MAXSIZE_TEMP_ARRAY(chunk, 2);
+ MAXSIZE_TEMP_ARRAY(chunks, 1);
+ ADD_C(chunk, CSTR_AS_OBJ(s));
+ ADD_C(chunk, INTEGER_OBJ(hl_id));
+ ADD_C(chunks, ARRAY_OBJ(chunk));
+ nvim_echo(chunks, false, &opts, &err);
+ ui_flush();
+ return s;
+}
+
void hl_msg_free(HlMessage hl_msg)
{
for (size_t i = 0; i < kv_size(hl_msg); i++) {