summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Brabandt <cb@256bit.org>2022-12-16 16:41:23 +0000
committerBram Moolenaar <Bram@vim.org>2022-12-16 16:41:23 +0000
commit9aee8ec400fe617f6d82441c46a22d0cef6fa3e6 (patch)
treed8ef22c2177d59f1196dc7d82c540612eff3813c
parent4ab1f4a32f7e0fcafa8f542429f1f6c47dcd5d2c (diff)
downloadvim-git-9.0.1064.tar.gz
patch 9.0.1064: code for making 'shortmess' temporarily empty is repeatedv9.0.1064
Problem: Code for making 'shortmess' temporarily empty is repeated. Solution: Add functions for making 'shortmess' empty and restoring it. (Christian Brabandt, closes #11709)
-rw-r--r--src/errors.h2
-rw-r--r--src/ex_cmds2.c25
-rw-r--r--src/option.h2
-rw-r--r--src/optionstr.c40
-rw-r--r--src/proto/optionstr.pro2
-rw-r--r--src/testdir/test_autocmd.vim55
-rw-r--r--src/version.c2
7 files changed, 111 insertions, 17 deletions
diff --git a/src/errors.h b/src/errors.h
index 6299ccd56..23071e10a 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -3389,3 +3389,5 @@ EXTERN char e_object_member_not_found_str[]
EXTERN char e_object_member_is_not_writable_str[]
INIT(= N_("E1335: Object member is not writable: %s"));
#endif
+EXTERN char e_internal_error_shortmess_too_long[]
+ INIT(= N_("E1336: Internal error: shortmess too long"));
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 9c00b80b7..3bdbede13 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -460,7 +460,6 @@ ex_listdo(exarg_T *eap)
#if defined(FEAT_SYN_HL)
char_u *save_ei = NULL;
#endif
- char_u *p_shm_save;
#ifdef FEAT_QUICKFIX
int qf_size = 0;
int qf_idx;
@@ -541,7 +540,9 @@ ex_listdo(exarg_T *eap)
buf = NULL;
else
{
+ save_clear_shm_value();
ex_cc(eap);
+ restore_shm_value();
buf = curbuf;
i = eap->line1 - 1;
@@ -568,13 +569,9 @@ ex_listdo(exarg_T *eap)
{
// Clear 'shm' to avoid that the file message overwrites
// any output from the command.
- p_shm_save = vim_strsave(p_shm);
- set_option_value_give_err((char_u *)"shm",
- 0L, (char_u *)"", 0);
+ save_clear_shm_value();
do_argfile(eap, i);
- set_option_value_give_err((char_u *)"shm",
- 0L, p_shm_save, 0);
- vim_free(p_shm_save);
+ restore_shm_value();
}
if (curwin->w_arg_idx != i)
break;
@@ -630,11 +627,9 @@ 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 = vim_strsave(p_shm);
- set_option_value_give_err((char_u *)"shm", 0L, (char_u *)"", 0);
+ save_clear_shm_value();
goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
- set_option_value_give_err((char_u *)"shm", 0L, p_shm_save, 0);
- vim_free(p_shm_save);
+ restore_shm_value();
// If autocommands took us elsewhere, quit here.
if (curbuf->b_fnum != next_fnum)
@@ -650,13 +645,9 @@ ex_listdo(exarg_T *eap)
qf_idx = qf_get_cur_idx(eap);
- // Clear 'shm' to avoid that the file message overwrites
- // any output from the command.
- p_shm_save = vim_strsave(p_shm);
- set_option_value_give_err((char_u *)"shm", 0L, (char_u *)"", 0);
+ save_clear_shm_value();
ex_cnext(eap);
- set_option_value_give_err((char_u *)"shm", 0L, p_shm_save, 0);
- vim_free(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/option.h b/src/option.h
index a11fa4167..aa55bfbac 100644
--- a/src/option.h
+++ b/src/option.h
@@ -271,6 +271,8 @@ typedef enum {
#define SHM_SEARCHCOUNT 'S' // search stats: '[1/10]'
#define SHM_POSIX "AS" // POSIX value
#define SHM_ALL "rmfixlnwaWtToOsAIcCqFS" // all possible flags for 'shm'
+#define SHM_LEN 30 // max length of all flags together
+ // plus a NUL character
// characters for p_go:
#define GO_TERMINAL '!' // use terminal for system commands
diff --git a/src/optionstr.c b/src/optionstr.c
index 08b9ebcfb..f3bc28582 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -13,6 +13,9 @@
#include "vim.h"
+static char_u shm_buf[SHM_LEN];
+static int set_shm_recursive = 0;
+
static char *(p_ambw_values[]) = {"single", "double", NULL};
static char *(p_bg_values[]) = {"light", "dark", NULL};
static char *(p_bkc_values[]) = {"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL};
@@ -2697,3 +2700,40 @@ check_ff_value(char_u *p)
{
return check_opt_strings(p, p_ff_values, FALSE);
}
+
+/*
+ * 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()
+{
+ 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((char_u *)"shm", 0L, (char_u *)"", 0);
+ }
+}
+
+/*
+ * Restore the shortmess Flags set from the save_clear_shm_value() function.
+ */
+ void
+restore_shm_value()
+{
+ if (--set_shm_recursive == 0)
+ {
+ set_option_value_give_err((char_u *)"shm", 0L, shm_buf, 0);
+ vim_memset(shm_buf, 0, SHM_LEN);
+ }
+}
diff --git a/src/proto/optionstr.pro b/src/proto/optionstr.pro
index 1fa6c562c..e75e3dcdb 100644
--- a/src/proto/optionstr.pro
+++ b/src/proto/optionstr.pro
@@ -11,4 +11,6 @@ void set_string_option_direct_in_buf(buf_T *buf, char_u *name, int opt_idx, char
char *set_string_option(int opt_idx, char_u *value, int opt_flags);
char *did_set_string_option(int opt_idx, char_u **varp, char_u *oldval, char *errbuf, int opt_flags, int *value_checked);
int check_ff_value(char_u *p);
+void save_clear_shm_value(void);
+void restore_shm_value(void);
/* vim: set ft=c : */
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 1eb7bb041..cf3d6fca1 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -4161,5 +4161,60 @@ func Test_autocmd_nested_setbufvar()
%bwipe!
endfunc
+func SetupVimTest_shm()
+ let g:bwe = []
+ let g:brp = []
+ set shortmess+=F
+
+ let dirname='XVimTestSHM'
+ call mkdir(dirname, 'R')
+ call writefile(['test'], dirname .. '/1')
+ call writefile(['test'], dirname .. '/2')
+ call writefile(['test'], dirname .. '/3')
+
+ augroup test
+ autocmd!
+ autocmd BufWinEnter * call add(g:bwe, $'BufWinEnter: {expand('<amatch>')}')
+ autocmd BufReadPost * call add(g:brp, $'BufReadPost: {expand('<amatch>')}')
+ augroup END
+
+ call setqflist([
+ \ {'filename': dirname .. '/1', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0},
+ \ {'filename': dirname .. '/2', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0},
+ \ {'filename': dirname .. '/3', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0}
+ \ ])
+ cdo! substitute/test/TEST
+
+ " clean up
+ noa enew!
+ set shortmess&vim
+ augroup test
+ autocmd!
+ augroup END
+ augroup! test
+endfunc
+
+func Test_autocmd_shortmess()
+ CheckNotMSWindows
+
+ call SetupVimTest_shm()
+ let output = execute(':mess')->split('\n')
+
+ let info = copy(output)->filter({idx, val -> val =~# '\d of 3'} )
+ let bytes = copy(output)->filter({idx, val -> val =~# 'bytes'} )
+
+ " We test the following here:
+ " BufReadPost should have been triggered 3 times, once per file
+ " BufWinEnter should have been triggered 3 times, once per file
+ " FileInfoMessage should have been shown 3 times, regardless of shm option
+ " "(x of 3)" message from :cnext has been shown 3 times
+
+ call assert_equal(3, g:brp->len())
+ call assert_equal(3, g:bwe->len())
+ call assert_equal(3, info->len())
+ call assert_equal(3, bytes->len())
+
+ delfunc SetupVimTest_shm
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 316d21313..140fa87cb 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1064,
+/**/
1063,
/**/
1062,