Skip to content

Commit e023d49

Browse files
haya14busabrammool
authored andcommitted
patch 8.2.4329: no support for end line number and column in 'errorformat'
Problem: No support for end line number and column in 'errorformat'. Solution: Add %e and %k. (closes #9624)
1 parent 73a16c2 commit e023d49

File tree

4 files changed

+88
-18
lines changed

4 files changed

+88
-18
lines changed

runtime/doc/quickfix.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,12 +1385,17 @@ Basic items
13851385
%f file name (finds a string)
13861386
%o module name (finds a string)
13871387
%l line number (finds a number)
1388+
%e end line number (finds a number)
13881389
%c column number (finds a number representing character
13891390
column of the error, byte index, a <tab> is 1
13901391
character column)
13911392
%v virtual column number (finds a number representing
13921393
screen column of the error (1 <tab> == 8 screen
13931394
columns))
1395+
%k end column number (finds a number representing
1396+
the character column of the error, byte index, or a
1397+
number representing screen end column of the error if
1398+
it's used with %v)
13941399
%t error type (finds a single character):
13951400
e - error message
13961401
w - warning message

src/quickfix.c

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ struct qf_info_S
118118
static qf_info_T ql_info; // global quickfix list
119119
static int_u last_qf_id = 0; // Last used quickfix list id
120120

121-
#define FMT_PATTERNS 11 // maximum number of % recognized
121+
#define FMT_PATTERNS 13 // maximum number of % recognized
122122

123123
/*
124124
* Structure used to hold the info of one part of 'errorformat'
@@ -224,23 +224,30 @@ static bufref_T qf_last_bufref = {NULL, 0, 0};
224224
*/
225225
#define LINE_MAXLEN 4096
226226

227+
/*
228+
* Patterns used. Keep in sync with qf_parse_fmt[].
229+
*/
227230
static struct fmtpattern
228231
{
229232
char_u convchar;
230233
char *pattern;
231234
} fmt_pat[FMT_PATTERNS] =
232235
{
233236
{'f', ".\\+"}, // only used when at end
234-
{'n', "\\d\\+"},
235-
{'l', "\\d\\+"},
236-
{'c', "\\d\\+"},
237-
{'t', "."},
238-
{'m', ".\\+"},
239-
{'r', ".*"},
240-
{'p', "[- .]*"},
241-
{'v', "\\d\\+"},
242-
{'s', ".\\+"},
243-
{'o', ".\\+"}
237+
{'n', "\\d\\+"}, // 1
238+
{'l', "\\d\\+"}, // 2
239+
{'e', "\\d\\+"}, // 3
240+
{'c', "\\d\\+"}, // 4
241+
{'k', "\\d\\+"}, // 5
242+
{'t', "."}, // 6
243+
#define FMT_PATTERN_M 7
244+
{'m', ".\\+"}, // 7
245+
#define FMT_PATTERN_R 8
246+
{'r', ".*"}, // 8
247+
{'p', "[- .]*"}, // 9
248+
{'v', "\\d\\+"}, // 10
249+
{'s', ".\\+"}, // 11
250+
{'o', ".\\+"} // 12
244251
};
245252

246253
/*
@@ -265,9 +272,9 @@ efmpat_to_regpat(
265272
semsg(_(e_too_many_chr_in_format_string), *efmpat);
266273
return NULL;
267274
}
268-
if ((idx && idx < 6
275+
if ((idx && idx < FMT_PATTERN_R
269276
&& vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
270-
|| (idx == 6
277+
|| (idx == FMT_PATTERN_R
271278
&& vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
272279
{
273280
semsg(_(e_unexpected_chr_in_format_str), *efmpat);
@@ -948,7 +955,7 @@ qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
948955
}
949956

950957
/*
951-
* Parse the match for line number (%l') pattern in regmatch.
958+
* Parse the match for line number ('%l') pattern in regmatch.
952959
* Return the matched value in "fields->lnum".
953960
*/
954961
static int
@@ -960,6 +967,19 @@ qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
960967
return QF_OK;
961968
}
962969

970+
/*
971+
* Parse the match for end line number ('%e') pattern in regmatch.
972+
* Return the matched value in "fields->end_lnum".
973+
*/
974+
static int
975+
qf_parse_fmt_e(regmatch_T *rmp, int midx, qffields_T *fields)
976+
{
977+
if (rmp->startp[midx] == NULL)
978+
return QF_FAIL;
979+
fields->end_lnum = atol((char *)rmp->startp[midx]);
980+
return QF_OK;
981+
}
982+
963983
/*
964984
* Parse the match for column number ('%c') pattern in regmatch.
965985
* Return the matched value in "fields->col".
@@ -973,6 +993,19 @@ qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
973993
return QF_OK;
974994
}
975995

996+
/*
997+
* Parse the match for end column number ('%k') pattern in regmatch.
998+
* Return the matched value in "fields->end_col".
999+
*/
1000+
static int
1001+
qf_parse_fmt_k(regmatch_T *rmp, int midx, qffields_T *fields)
1002+
{
1003+
if (rmp->startp[midx] == NULL)
1004+
return QF_FAIL;
1005+
fields->end_col = (int)atol((char *)rmp->startp[midx]);
1006+
return QF_OK;
1007+
}
1008+
9761009
/*
9771010
* Parse the match for error type ('%t') pattern in regmatch.
9781011
* Return the matched value in "fields->type".
@@ -1132,16 +1165,19 @@ qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
11321165
* 'errorformat' format pattern parser functions.
11331166
* The '%f' and '%r' formats are parsed differently from other formats.
11341167
* See qf_parse_match() for details.
1168+
* Keep in sync with fmt_pat[].
11351169
*/
11361170
static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
11371171
{
1138-
NULL,
1172+
NULL, // %f
11391173
qf_parse_fmt_n,
11401174
qf_parse_fmt_l,
1175+
qf_parse_fmt_e,
11411176
qf_parse_fmt_c,
1177+
qf_parse_fmt_k,
11421178
qf_parse_fmt_t,
11431179
qf_parse_fmt_m,
1144-
NULL,
1180+
NULL, // %r
11451181
qf_parse_fmt_p,
11461182
qf_parse_fmt_v,
11471183
qf_parse_fmt_s,
@@ -1186,14 +1222,14 @@ qf_parse_match(
11861222
midx = (int)fmt_ptr->addr[i];
11871223
if (i == 0 && midx > 0) // %f
11881224
status = qf_parse_fmt_f(regmatch, midx, fields, idx);
1189-
else if (i == 5)
1225+
else if (i == FMT_PATTERN_M)
11901226
{
11911227
if (fmt_ptr->flags == '+' && !qf_multiscan) // %+
11921228
status = copy_nonerror_line(linebuf, linelen, fields);
11931229
else if (midx > 0) // %m
11941230
status = qf_parse_fmt_m(regmatch, midx, fields);
11951231
}
1196-
else if (i == 6 && midx > 0) // %r
1232+
else if (i == FMT_PATTERN_R && midx > 0) // %r
11971233
status = qf_parse_fmt_r(regmatch, midx, tail);
11981234
else if (midx > 0) // others
11991235
status = (qf_parse_fmt[i])(regmatch, midx, fields);
@@ -1363,11 +1399,15 @@ qf_parse_multiline_pfx(
13631399

13641400
if (!qfprev->qf_lnum)
13651401
qfprev->qf_lnum = fields->lnum;
1402+
if (!qfprev->qf_end_lnum)
1403+
qfprev->qf_end_lnum = fields->end_lnum;
13661404
if (!qfprev->qf_col)
13671405
{
13681406
qfprev->qf_col = fields->col;
13691407
qfprev->qf_viscol = fields->use_viscol;
13701408
}
1409+
if (!qfprev->qf_end_col)
1410+
qfprev->qf_end_col = fields->end_col;
13711411
if (!qfprev->qf_fnum)
13721412
qfprev->qf_fnum = qf_get_fnum(qfl,
13731413
qfl->qf_directory,

src/testdir/test_quickfix.vim

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,6 +1469,29 @@ func Test_efm_error_type()
14691469
let &efm = save_efm
14701470
endfunc
14711471

1472+
" Test for end_lnum ('%e') and end_col ('%k') fields in 'efm'
1473+
func Test_efm_end_lnum_col()
1474+
let save_efm = &efm
1475+
1476+
" single line
1477+
set efm=%f:%l-%e:%c-%k:%t:%m
1478+
cexpr ["Xfile1:10-20:1-2:E:msg1", "Xfile1:20-30:2-3:W:msg2",]
1479+
let output = split(execute('clist'), "\n")
1480+
call assert_equal([
1481+
\ ' 1 Xfile1:10-20 col 1-2 error: msg1',
1482+
\ ' 2 Xfile1:20-30 col 2-3 warning: msg2'], output)
1483+
1484+
" multiple lines
1485+
set efm=%A%n)%m,%Z%f:%l-%e:%c-%k
1486+
cexpr ["1)msg1", "Xfile1:14-24:1-2",
1487+
\ "2)msg2", "Xfile1:24-34:3-4"]
1488+
let output = split(execute('clist'), "\n")
1489+
call assert_equal([
1490+
\ ' 1 Xfile1:14-24 col 1-2 error 1: msg1',
1491+
\ ' 2 Xfile1:24-34 col 3-4 error 2: msg2'], output)
1492+
let &efm = save_efm
1493+
endfunc
1494+
14721495
func XquickfixChangedByAutocmd(cchar)
14731496
call s:setup_commands(a:cchar)
14741497
if a:cchar == 'c'

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,8 @@ static char *(features[]) =
746746

747747
static int included_patches[] =
748748
{ /* Add new patch number below this line */
749+
/**/
750+
4329,
749751
/**/
750752
4328,
751753
/**/

0 commit comments

Comments
 (0)