patch 9.1.1396: 'errorformat' is a global option
Problem: The 'grepformat' option is global option, but it would be
useful to have it buffer-local, similar to 'errorformat' and
other quickfix related options (Dani Dickstein)
Solution: Add the necessary code to support global-local 'grepformat',
allowing different buffers to parse different grep output
formats (glepnir)
fixes: #17316
closes: #17315
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 274d56e..e74c5e8 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 9.1. Last change: 2025 May 14
+*options.txt* For Vim version 9.1. Last change: 2025 May 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4062,7 +4062,7 @@
*'grepformat'* *'gfm'*
'grepformat' 'gfm' string (default "%f:%l:%m,%f:%l%m,%f %l%m")
- global
+ global or local to buffer |global-local|
Format to recognize for the ":grep" command output.
This is a scanf-like string that uses the same format as the
'errorformat' option: see |errorformat|.
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 5242842..e03deed 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.1. Last change: 2025 May 14
+*version9.txt* For Vim version 9.1. Last change: 2025 May 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -41634,17 +41634,19 @@
- the default for 'commentstring' contains whitespace padding to have
automatic comments look nicer |comment-install|
- 'completeopt' is now a |global-local| option.
-- 'nrformats' accepts the new "blank" suboption, to determine a signed or
- unsigned number based on whitespace in front of a minus sign.
- add 'cpoptions' flag "z" |cpo-z|, to disable some (traditional) vi
behaviour/inconsistency (see |d-special| and |cw|).
+- new option values for 'fillchars':
+ "trunc" - configure truncation indicator, 'pummaxwidth'
+ "truncrl" - like "trunc" but in 'rl' mode, 'pummaxwidth'
+ "tpl_vert" - separators for the 'tabpanel'
+- 'grepformat' is now a |global-local| option.
+- adjust for GTK3 dropping some mouse cursors 'mouseshape'
+- 'nrformats' accepts the new "blank" suboption, to determine a signed or
+ unsigned number based on whitespace in front of a minus sign.
- 'rulerformat' now supports the |stl-%!| item
- use 'smoothscroll' logic for CTRL-F / CTRL-B for pagewise scrolling
and CTRL-D / CTRL-U for half-pagewise scrolling
-- New option value for 'fillchars':
- "trunc" - configure truncation indicator, 'pummaxwidth'
- "truncrl" - like "trunc" but in 'rl' mode, 'pummaxwidth'
-- adjust for GTK3 dropping some mouse cursors 'mouseshape'
Ex commands: ~
- allow to specify a priority when defining a new sign |:sign-define|
diff --git a/src/buffer.c b/src/buffer.c
index 48e8cb6..fe19269 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2508,6 +2508,7 @@
free_callback(&buf->b_tsrfu_cb);
#endif
#ifdef FEAT_QUICKFIX
+ clear_string_option(&buf->b_p_gefm);
clear_string_option(&buf->b_p_gp);
clear_string_option(&buf->b_p_mp);
clear_string_option(&buf->b_p_efm);
diff --git a/src/option.c b/src/option.c
index d6a0098..85c3705 100644
--- a/src/option.c
+++ b/src/option.c
@@ -6429,6 +6429,9 @@
case PV_EFM:
clear_string_option(&buf->b_p_efm);
break;
+ case PV_GEFM:
+ clear_string_option(&buf->b_p_gefm);
+ break;
case PV_GP:
clear_string_option(&buf->b_p_gp);
break;
@@ -6508,6 +6511,7 @@
#endif
#ifdef FEAT_QUICKFIX
case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
+ case PV_GEFM: return (char_u *)&(curbuf->b_p_gefm);
case PV_GP: return (char_u *)&(curbuf->b_p_gp);
case PV_MP: return (char_u *)&(curbuf->b_p_mp);
#endif
@@ -6626,6 +6630,8 @@
#ifdef FEAT_QUICKFIX
case PV_EFM: return *curbuf->b_p_efm != NUL
? (char_u *)&(curbuf->b_p_efm) : p->var;
+ case PV_GEFM: return *curbuf->b_p_gefm != NUL
+ ? (char_u *)&(curbuf->b_p_gefm) : p->var;
case PV_GP: return *curbuf->b_p_gp != NUL
? (char_u *)&(curbuf->b_p_gp) : p->var;
case PV_MP: return *curbuf->b_p_mp != NUL
@@ -7415,6 +7421,7 @@
buf->b_p_bkc = empty_option;
buf->b_bkc_flags = 0;
#ifdef FEAT_QUICKFIX
+ buf->b_p_gefm = empty_option;
buf->b_p_gp = empty_option;
buf->b_p_mp = empty_option;
buf->b_p_efm = empty_option;
diff --git a/src/option.h b/src/option.h
index e78a7cb..740f6ee 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1157,6 +1157,7 @@
, BV_BT
#ifdef FEAT_QUICKFIX
, BV_EFM
+ , BV_GEFM
, BV_GP
, BV_MP
#endif
diff --git a/src/optiondefs.h b/src/optiondefs.h
index d509463..cb4376c 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -33,6 +33,7 @@
#define PV_BT OPT_BUF(BV_BT)
#ifdef FEAT_QUICKFIX
# define PV_EFM OPT_BOTH(OPT_BUF(BV_EFM))
+# define PV_GEFM OPT_BOTH(OPT_BUF(BV_GEFM))
# define PV_GP OPT_BOTH(OPT_BUF(BV_GP))
# define PV_MP OPT_BOTH(OPT_BUF(BV_MP))
#endif
@@ -1154,7 +1155,7 @@
{(char_u *)FALSE, (char_u *)0L} SCTX_INIT},
{"grepformat", "gfm", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
#ifdef FEAT_QUICKFIX
- (char_u *)&p_gefm, PV_NONE, NULL, NULL,
+ (char_u *)&p_gefm, PV_GEFM, NULL, NULL,
{(char_u *)DFLT_GREPFORMAT, (char_u *)0L}
#else
(char_u *)NULL, PV_NONE, NULL, NULL,
diff --git a/src/optionstr.c b/src/optionstr.c
index 8e233e8..7a1cd69 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -327,6 +327,7 @@
check_string_option(&buf->b_p_keymap);
#endif
#ifdef FEAT_QUICKFIX
+ check_string_option(&buf->b_p_gefm);
check_string_option(&buf->b_p_gp);
check_string_option(&buf->b_p_mp);
check_string_option(&buf->b_p_efm);
diff --git a/src/quickfix.c b/src/quickfix.c
index d012ea0..ab595d7 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -5503,7 +5503,7 @@
incr_quickfix_busy();
if (eap->cmdidx != CMD_make && eap->cmdidx != CMD_lmake)
- errorformat = p_gefm;
+ errorformat = *curbuf->b_p_gefm != NUL ? curbuf->b_p_gefm : p_gefm;
if (eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd)
newlist = FALSE;
diff --git a/src/structs.h b/src/structs.h
index cd7370d..00b0746 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3371,6 +3371,7 @@
* local values for options which are normally global
*/
#ifdef FEAT_QUICKFIX
+ char_u *b_p_gefm; // 'grepformat' local value
char_u *b_p_gp; // 'grepprg' local value
char_u *b_p_mp; // 'makeprg' local value
char_u *b_p_efm; // 'errorformat' local value
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index fe85887..dc2a2a4 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -2379,6 +2379,25 @@
call s:test_xgrep('l')
endfunc
+func Test_local_grepformat()
+ let save_grepformat = &grepformat
+ set grepformat=%f:%l:%m
+ " The following line are used for the local grep test. Don't remove.
+ " UNIQUEPREFIX:2:3: Local grepformat test
+ new
+ setlocal grepformat=UNIQUEPREFIX:%c:%n:%m
+ call assert_equal('UNIQUEPREFIX:%c:%n:%m', &l:grepformat)
+ call assert_equal('%f:%l:%m', &g:grepformat)
+
+ set grepprg=internal
+ silent grep "^[[:space:]]*\" UNIQUEPREFIX:" test_quickfix.vim
+ call assert_equal(1, len(getqflist()))
+ set grepprg&vim
+
+ bwipe!
+ let &grepformat = save_grepformat
+endfunc
+
func Test_two_windows()
" Use one 'errorformat' for two windows. Add an expression to each of them,
" make sure they each keep their own state.
diff --git a/src/version.c b/src/version.c
index e367036..f282c1f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -710,6 +710,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1396,
+/**/
1395,
/**/
1394,