From 99384fcd9c295b5f1894c550cf3727cd1ad4c6bd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 17 May 2025 08:20:20 +0800 Subject: [PATCH] vim-patch:9.1.1396: 'grepformat' is a global option (#34060) 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: vim/vim#17316 closes: vim/vim#17315 https://github.com/vim/vim/commit/7b9eb6389d693dafcd502cda2ffc62564a2dbba9 Co-authored-by: glepnir --- runtime/doc/news.txt | 1 + runtime/doc/options.txt | 2 +- runtime/lua/vim/_meta/options.lua | 2 ++ src/nvim/buffer.c | 1 + src/nvim/buffer_defs.h | 1 + src/nvim/option.c | 5 +++++ src/nvim/options.lua | 2 +- src/nvim/optionstr.c | 1 + src/nvim/quickfix.c | 2 +- test/old/testdir/test_quickfix.vim | 19 +++++++++++++++++++ 10 files changed, 33 insertions(+), 3 deletions(-) diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 0058be7f2f..b30c1d5065 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -167,6 +167,7 @@ OPTIONS |ins-completion| modes. • 'completeopt' flag "nearset" sorts completion results by distance to cursor. • 'diffopt' `inline:` configures diff highlighting for changes within a line. +• 'grepformat' is now a |global-local| option. • 'pummaxwidth' sets maximum width for the completion popup menu. • 'winborder' "bold" style. • |g:clipboard| accepts a string name to force any builtin clipboard tool. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 5fabe6efe9..574e0b9efb 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3034,7 +3034,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'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/lua/vim/_meta/options.lua b/runtime/lua/vim/_meta/options.lua index 79035d420d..b77b135f92 100644 --- a/runtime/lua/vim/_meta/options.lua +++ b/runtime/lua/vim/_meta/options.lua @@ -2822,6 +2822,8 @@ vim.go.gd = vim.go.gdefault --- @type string vim.o.grepformat = "%f:%l:%m,%f:%l%m,%f %l%m" vim.o.gfm = vim.o.grepformat +vim.bo.grepformat = vim.o.grepformat +vim.bo.gfm = vim.bo.grepformat vim.go.grepformat = vim.o.grepformat vim.go.gfm = vim.go.grepformat diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 632ce35ece..6c3204fde1 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2098,6 +2098,7 @@ void free_buf_options(buf_T *buf, bool free_p_ff) callback_free(&buf->b_ofu_cb); clear_string_option(&buf->b_p_tsrfu); callback_free(&buf->b_tsrfu_cb); + 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/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index af2b939fb4..96d811642d 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -606,6 +606,7 @@ struct file_buffer { char *b_p_keymap; ///< 'keymap' // local values for options which are normally global + char *b_p_gefm; ///< 'grepformat' local value char *b_p_gp; ///< 'grepprg' local value char *b_p_mp; ///< 'makeprg' local value char *b_p_efm; ///< 'errorformat' local value diff --git a/src/nvim/option.c b/src/nvim/option.c index ae4520d9e1..d790ce2871 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4436,6 +4436,8 @@ void *get_varp_scope_from(vimoption_T *p, int opt_flags, buf_T *buf, win_T *win) return &(buf->b_p_ffu); case kOptErrorformat: return &(buf->b_p_efm); + case kOptGrepformat: + return &(buf->b_p_gefm); case kOptGrepprg: return &(buf->b_p_gp); case kOptMakeprg: @@ -4563,6 +4565,8 @@ void *get_varp_from(vimoption_T *p, buf_T *buf, win_T *win) return *buf->b_p_ffu != NUL ? &(buf->b_p_ffu) : p->var; case kOptErrorformat: return *buf->b_p_efm != NUL ? &(buf->b_p_efm) : p->var; + case kOptGrepformat: + return *buf->b_p_gefm != NUL ? &(buf->b_p_gefm) : p->var; case kOptGrepprg: return *buf->b_p_gp != NUL ? &(buf->b_p_gp) : p->var; case kOptMakeprg: @@ -5224,6 +5228,7 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_ul = NO_LOCAL_UNDOLEVEL; buf->b_p_bkc = empty_string_option; buf->b_bkc_flags = 0; + buf->b_p_gefm = empty_string_option; buf->b_p_gp = empty_string_option; buf->b_p_mp = empty_string_option; buf->b_p_efm = empty_string_option; diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 8e5b374938..f6e24d0e04 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -3694,7 +3694,7 @@ local options = { ]=], full_name = 'grepformat', list = 'onecomma', - scope = { 'global' }, + scope = { 'global', 'buf' }, short_desc = N_("format of 'grepprg' output"), type = 'string', varname = 'p_gefm', diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index c66526318e..5442fc40e0 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -154,6 +154,7 @@ void check_buf_options(buf_T *buf) check_string_option(&buf->b_p_cfu); check_string_option(&buf->b_p_ofu); check_string_option(&buf->b_p_keymap); + 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/nvim/quickfix.c b/src/nvim/quickfix.c index 49fbb84318..74c4516ef1 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4595,7 +4595,7 @@ void ex_make(exarg_T *eap) incr_quickfix_busy(); char *errorformat = (eap->cmdidx != CMD_make && eap->cmdidx != CMD_lmake) - ? p_gefm + ? *curbuf->b_p_gefm != NUL ? curbuf->b_p_gefm : p_gefm : p_efm; bool newlist = eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd; diff --git a/test/old/testdir/test_quickfix.vim b/test/old/testdir/test_quickfix.vim index 000526780f..3d4998beba 100644 --- a/test/old/testdir/test_quickfix.vim +++ b/test/old/testdir/test_quickfix.vim @@ -2220,6 +2220,25 @@ func Test_grep() 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.