mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
vim-patch:9.0.2064: cannot use buffer-number for errorformat (#25782)
Problem: cannot use buffer-number for errorformat
Solution: add support for parsing a buffer number using '%b' in
'errorformat'
closes: vim/vim#13419
b731800522
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
parent
bfe8a39512
commit
f2fc44550f
@ -1381,6 +1381,7 @@ rest is ignored. Items can only be 1023 bytes long.
|
||||
Basic items
|
||||
|
||||
%f file name (finds a string)
|
||||
%b buffer number (finds a number)
|
||||
%o module name (finds a string)
|
||||
%l line number (finds a number)
|
||||
%e end line number (finds a number)
|
||||
@ -1420,6 +1421,11 @@ On Windows a leading "C:" will be included in "%f", even when using "%f:".
|
||||
This means that a file name which is a single alphabetical letter will not be
|
||||
detected.
|
||||
|
||||
The "%b" conversion is used to parse a buffer number. This is useful for
|
||||
referring to lines in a scratch buffer or a buffer with no name. If a buffer
|
||||
with the matching number doesn't exist, then that line is used as a non-error
|
||||
line.
|
||||
|
||||
The "%p" conversion is normally followed by a "^". It's used for compilers
|
||||
that output a line like: >
|
||||
^
|
||||
|
@ -152,7 +152,7 @@ struct qf_info_S {
|
||||
static qf_info_T ql_info; // global quickfix list
|
||||
static unsigned 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'
|
||||
typedef struct efm_S efm_T;
|
||||
@ -217,6 +217,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
char *namebuf;
|
||||
int bnr;
|
||||
char *module;
|
||||
char *errmsg;
|
||||
size_t errmsglen;
|
||||
@ -344,7 +345,7 @@ static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T
|
||||
: ((qfl->qf_currfile != NULL && fields->valid)
|
||||
? qfl->qf_currfile : NULL),
|
||||
fields->module,
|
||||
0,
|
||||
fields->bnr,
|
||||
fields->errmsg,
|
||||
fields->lnum,
|
||||
fields->end_lnum,
|
||||
@ -391,20 +392,21 @@ static struct fmtpattern {
|
||||
char *pattern;
|
||||
} 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', "[- \t.]*" }, // 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', "[-\t .]*" }, // 10
|
||||
{ 'v', "\\d\\+" }, // 11
|
||||
{ 's', ".\\+" }, // 12
|
||||
{ 'o', ".\\+" } // 13
|
||||
};
|
||||
|
||||
/// Convert an errorformat pattern to a regular expression pattern.
|
||||
@ -1312,6 +1314,21 @@ static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int pre
|
||||
return QF_OK;
|
||||
}
|
||||
|
||||
/// Parse the match for buffer number ('%b') pattern in regmatch.
|
||||
/// Return the matched value in "fields->bnr".
|
||||
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(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)
|
||||
@ -1496,6 +1513,7 @@ static int qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
|
||||
/// Keep in sync with fmt_pat[].
|
||||
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,
|
||||
@ -1568,6 +1586,7 @@ static int qf_parse_get_fields(char *linebuf, size_t linelen, efm_T *fmt_ptr, qf
|
||||
}
|
||||
|
||||
fields->namebuf[0] = NUL;
|
||||
fields->bnr = 0;
|
||||
fields->module[0] = NUL;
|
||||
fields->pattern[0] = NUL;
|
||||
if (!qf_multiscan) {
|
||||
|
@ -6320,4 +6320,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
|
||||
|
Loading…
Reference in New Issue
Block a user