summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2023-10-25 20:50:28 +0200
committerChristian Brabandt <cb@256bit.org>2023-10-25 20:50:28 +0200
commitb731800522af00fd348814d33a065b92e698afc3 (patch)
tree7607eb64e4a8475a13341590ac6cd7bd7f2f499d /src
parent5985879e3c36383155f84649fa42d06813a1893e (diff)
patch 9.0.2064: cannot use buffer-number for errorformatv9.0.2064
Problem: cannot use buffer-number for errorformat Solution: add support for parsing a buffer number using '%b' in 'errorformat' closes: #13419 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Diffstat (limited to 'src')
-rw-r--r--src/quickfix.c52
-rw-r--r--src/testdir/test_quickfix.vim49
-rw-r--r--src/version.c2
3 files changed, 87 insertions, 16 deletions
diff --git a/src/quickfix.c b/src/quickfix.c
index a3d3e8fb79..45b58c44d9 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -120,7 +120,7 @@ struct qf_info_S
static qf_info_T ql_info; // global quickfix list
static int_u last_qf_id = 0; // Last used quickfix list id
-#define FMT_PATTERNS 13 // maximum number of % recognized
+#define FMT_PATTERNS 14 // maximum number of % recognized
/*
* Structure used to hold the info of one part of 'errorformat'
@@ -275,20 +275,21 @@ static struct fmtpattern
} fmt_pat[FMT_PATTERNS] =
{
{'f', ".\\+"}, // only used when at end
- {'n', "\\d\\+"}, // 1
- {'l', "\\d\\+"}, // 2
- {'e', "\\d\\+"}, // 3
- {'c', "\\d\\+"}, // 4
- {'k', "\\d\\+"}, // 5
- {'t', "."}, // 6
-#define FMT_PATTERN_M 7
- {'m', ".\\+"}, // 7
-#define FMT_PATTERN_R 8
- {'r', ".*"}, // 8
- {'p', "[- .]*"}, // 9
- {'v', "\\d\\+"}, // 10
- {'s', ".\\+"}, // 11
- {'o', ".\\+"} // 12
+ {'b', "\\d\\+"}, // 1
+ {'n', "\\d\\+"}, // 2
+ {'l', "\\d\\+"}, // 3
+ {'e', "\\d\\+"}, // 4
+ {'c', "\\d\\+"}, // 5
+ {'k', "\\d\\+"}, // 6
+ {'t', "."}, // 7
+#define FMT_PATTERN_M 8
+ {'m', ".\\+"}, // 8
+#define FMT_PATTERN_R 9
+ {'r', ".*"}, // 9
+ {'p', "[- .]*"}, // 10
+ {'v', "\\d\\+"}, // 11
+ {'s', ".\\+"}, // 12
+ {'o', ".\\+"} // 13
};
/*
@@ -942,6 +943,7 @@ qf_get_nextline(qfstate_T *state)
typedef struct {
char_u *namebuf;
+ int bnr;
char_u *module;
char_u *errmsg;
int errmsglen;
@@ -989,6 +991,22 @@ qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix)
* Return the matched value in "fields->enr".
*/
static int
+qf_parse_fmt_b(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+ if (rmp->startp[midx] == NULL)
+ return QF_FAIL;
+ int bnr = (int)atol((char *)rmp->startp[midx]);
+ if (buflist_findnr(bnr) == NULL)
+ return QF_FAIL;
+ fields->bnr = bnr;
+ return QF_OK;
+}
+
+/*
+ * Parse the match for error number ('%n') pattern in regmatch.
+ * Return the matched value in "fields->enr".
+ */
+ static int
qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
{
if (rmp->startp[midx] == NULL)
@@ -1213,6 +1231,7 @@ qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
{
NULL, // %f
+ qf_parse_fmt_b,
qf_parse_fmt_n,
qf_parse_fmt_l,
qf_parse_fmt_e,
@@ -1309,6 +1328,7 @@ qf_parse_get_fields(
return QF_FAIL;
fields->namebuf[0] = NUL;
+ fields->bnr = 0;
fields->module[0] = NUL;
fields->pattern[0] = NUL;
if (!qf_multiscan)
@@ -1713,7 +1733,7 @@ qf_init_process_nextline(
: ((qfl->qf_currfile != NULL && fields->valid)
? qfl->qf_currfile : (char_u *)NULL),
fields->module,
- 0,
+ fields->bnr,
fields->errmsg,
fields->lnum,
fields->end_lnum,
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index 33ce700f0b..c784a2da59 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -6447,4 +6447,53 @@ func Test_quickfix_buffer_contents()
call setqflist([], 'f')
endfunc
+" Test for "%b" in "errorformat"
+func Test_efm_format_b()
+ call setqflist([], 'f')
+ new
+ call setline(1, ['1: abc', '1: def', '1: ghi'])
+ let b1 = bufnr()
+ new
+ call setline(1, ['2: abc', '2: def', '2: ghi'])
+ let b2 = bufnr()
+ new
+ call setline(1, ['3: abc', '3: def', '3: ghi'])
+ let b3 = bufnr()
+ new
+ let lines =<< trim eval END
+ {b1}:1:1
+ {b2}:2:2
+ {b3}:3:3
+ END
+ call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c'})
+ cfirst
+ call assert_equal([b1, 1, 1], [bufnr(), line('.'), col('.')])
+ cnext
+ call assert_equal([b2, 2, 2], [bufnr(), line('.'), col('.')])
+ cnext
+ call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
+ enew!
+
+ " Use a non-existing buffer
+ let lines =<< trim eval END
+ 9991:1:1:m1
+ 9992:2:2:m2
+ {b3}:3:3:m3
+ END
+ call setqflist([], ' ', #{lines: lines, efm: '%b:%l:%c:%m'})
+ cfirst | cnext
+ call assert_equal([b3, 3, 3], [bufnr(), line('.'), col('.')])
+ " Lines with non-existing buffer numbers should be used as non-error lines
+ call assert_equal([
+ \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
+ \ module: '', type: '', end_col: 0, col: 0, text: '9991:1:1:m1'},
+ \ #{lnum: 0, bufnr: 0, end_lnum: 0, pattern: '', valid: 0, vcol: 0, nr: -1,
+ \ module: '', type: '', end_col: 0, col: 0, text: '9992:2:2:m2'},
+ \ #{lnum: 3, bufnr: b3, end_lnum: 0, pattern: '', valid: 1, vcol: 0,
+ \ nr: -1, module: '', type: '', end_col: 0, col: 3, text: 'm3'}],
+ \ getqflist())
+ %bw!
+ call setqflist([], 'f')
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 3389927fa5..7651bcc46f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2064,
+/**/
2063,
/**/
2062,