aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/ex_cmds2.c22
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/optionstr.c33
3 files changed, 43 insertions, 13 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 6d190df939..4d71285447 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -38,6 +38,7 @@
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
+#include "nvim/optionstr.h"
#include "nvim/os/os_defs.h"
#include "nvim/path.h"
#include "nvim/pos.h"
@@ -467,7 +468,6 @@ void ex_listdo(exarg_T *eap)
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD)) {
int next_fnum = 0;
- char *p_shm_save;
int i = 0;
// start at the eap->line1 argument/window/buffer
wp = firstwin;
@@ -514,7 +514,9 @@ void ex_listdo(exarg_T *eap)
if (qf_size == 0 || (size_t)eap->line1 > qf_size) {
buf = NULL;
} else {
+ save_clear_shm_value();
ex_cc(eap);
+ restore_shm_value();
buf = curbuf;
i = (int)eap->line1 - 1;
@@ -541,11 +543,9 @@ void ex_listdo(exarg_T *eap)
if (curwin->w_arg_idx != i || !editing_arg_idx(curwin)) {
// Clear 'shm' to avoid that the file message overwrites
// any output from the command.
- p_shm_save = xstrdup(p_shm);
- set_option_value_give_err("shm", 0L, "", 0);
+ save_clear_shm_value();
do_argfile(eap, i);
- set_option_value_give_err("shm", 0L, p_shm_save, 0);
- xfree(p_shm_save);
+ restore_shm_value();
}
if (curwin->w_arg_idx != i) {
break;
@@ -610,11 +610,9 @@ void ex_listdo(exarg_T *eap)
// Go to the next buffer. Clear 'shm' to avoid that the file
// message overwrites any output from the command.
- p_shm_save = xstrdup(p_shm);
- set_option_value_give_err("shm", 0L, "", 0);
+ save_clear_shm_value();
goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
- set_option_value_give_err("shm", 0L, p_shm_save, 0);
- xfree(p_shm_save);
+ restore_shm_value();
// If autocommands took us elsewhere, quit here.
if (curbuf->b_fnum != next_fnum) {
@@ -633,11 +631,9 @@ void ex_listdo(exarg_T *eap)
// Clear 'shm' to avoid that the file message overwrites
// any output from the command.
- p_shm_save = xstrdup(p_shm);
- set_option_value_give_err("shm", 0L, "", 0);
+ save_clear_shm_value();
ex_cnext(eap);
- set_option_value_give_err("shm", 0L, p_shm_save, 0);
- xfree(p_shm_save);
+ restore_shm_value();
// If jumping to the next quickfix entry fails, quit here.
if (qf_get_cur_idx(eap) == qf_idx) {
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index b7ea8cd2c2..66d5b7280a 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -260,6 +260,7 @@ enum {
SHM_RECORDING = 'q', ///< Short recording message.
SHM_FILEINFO = 'F', ///< No file info messages.
SHM_SEARCHCOUNT = 'S', ///< Search stats: '[1/10]'
+ SHM_LEN = 30, ///< Max length of all flags together plus a NUL character.
};
/// Represented by 'a' flag.
#define SHM_ALL_ABBREVIATIONS ((char[]) { \
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 3372c7b6c6..6c6190cb08 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -67,6 +67,8 @@ static const char e_backupext_and_patchmode_are_equal[]
= N_("E589: 'backupext' and 'patchmode' are equal");
static const char e_showbreak_contains_unprintable_or_wide_character[]
= N_("E595: 'showbreak' contains unprintable or wide character");
+static const char e_internal_error_shortmess_too_long[]
+ = N_("E1336: Internal error: shortmess too long");
static char *(p_ambw_values[]) = { "single", "double", NULL };
static char *(p_bg_values[]) = { "light", "dark", NULL };
@@ -1941,6 +1943,37 @@ int check_ff_value(char *p)
return check_opt_strings(p, p_ff_values, false);
}
+static char shm_buf[SHM_LEN];
+static int set_shm_recursive = 0;
+
+/// Save the acutal shortmess Flags and clear them
+/// temporarily to avoid that file messages
+/// overwrites any output from the following commands.
+///
+/// Caller must make sure to first call save_clear_shm_value() and then
+/// restore_shm_value() exactly the same number of times.
+void save_clear_shm_value(void)
+{
+ if (strlen(p_shm) >= SHM_LEN) {
+ iemsg(e_internal_error_shortmess_too_long);
+ return;
+ }
+
+ if (++set_shm_recursive == 1) {
+ STRCPY(shm_buf, p_shm);
+ set_option_value_give_err("shm", 0L, "", 0);
+ }
+}
+
+/// Restore the shortmess Flags set from the save_clear_shm_value() function.
+void restore_shm_value(void)
+{
+ if (--set_shm_recursive == 0) {
+ set_option_value_give_err("shm", 0L, shm_buf, 0);
+ memset(shm_buf, 0, SHM_LEN);
+ }
+}
+
static const char e_conflicts_with_value_of_listchars[]
= N_("E834: Conflicts with value of 'listchars'");
static const char e_conflicts_with_value_of_fillchars[]